2023-09-18 09:46:54 -06:00
var doip = ( function ( exports , openpgp$1 , fetcher ) {
2023-07-09 04:05:21 -06:00
'use strict' ;
function _interopNamespaceDefault ( e ) {
var n = Object . create ( null ) ;
if ( e ) {
Object . keys ( e ) . forEach ( function ( k ) {
if ( k !== 'default' ) {
var d = Object . getOwnPropertyDescriptor ( e , k ) ;
Object . defineProperty ( n , k , d . get ? d : {
enumerable : true ,
get : function ( ) { return e [ k ] ; }
} ) ;
}
} ) ;
}
n . default = e ;
return Object . freeze ( n ) ;
}
var fetcher _ _namespace = /*#__PURE__*/ _interopNamespaceDefault ( fetcher ) ;
/ *
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
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 .
* /
/ * *
* Contains enums
* @ module enums
* /
/ * *
* The proxy policy that decides how to fetch a proof
* @ readonly
* @ enum { string }
* /
const ProxyPolicy = {
/** Proxy usage decision depends on environment and service provider */
ADAPTIVE : 'adaptive' ,
/** Always use a proxy */
ALWAYS : 'always' ,
/** Never use a proxy, skip a verification if a proxy is inevitable */
NEVER : 'never'
} ;
/ * *
* Methods for fetching proofs
* @ readonly
* @ enum { string }
* /
const Fetcher = {
/** HTTP requests to ActivityPub */
ACTIVITYPUB : 'activitypub' ,
/** DNS module from Node.js */
DNS : 'dns' ,
/** GraphQL over HTTP requests */
GRAPHQL : 'graphql' ,
/** Basic HTTP requests */
HTTP : 'http' ,
/** IRC module from Node.js */
IRC : 'irc' ,
/** HTTP request to Matrix API */
MATRIX : 'matrix' ,
/** HTTP request to Telegram API */
TELEGRAM : 'telegram' ,
/** XMPP module from Node.js */
XMPP : 'xmpp'
} ;
/ * *
* Entity encoding format
* @ readonly
* @ enum { string }
* /
const EntityEncodingFormat = {
/** No special formatting */
PLAIN : 'plain' ,
/** HTML encoded entities */
HTML : 'html' ,
/** XML encoded entities */
XML : 'xml'
} ;
/ * *
* Levels of access restriction for proof fetching
* @ readonly
* @ enum { string }
* /
const ProofAccessRestriction = {
/** Any HTTP request will work */
NONE : 'none' ,
/** CORS requests are denied */
NOCORS : 'nocors' ,
/** HTTP requests must contain API or access tokens */
GRANTED : 'granted' ,
/** Not accessible by HTTP request, needs server software */
SERVER : 'server'
} ;
/ * *
* Format of proof
* @ readonly
* @ enum { string }
* /
const ProofFormat = {
/** JSON format */
JSON : 'json' ,
/** Plaintext format */
TEXT : 'text'
} ;
/ * *
* Format of claim
* @ readonly
* @ enum { string }
* /
const ClaimFormat = {
/** `openpgp4fpr:123123123` */
URI : 'uri' ,
/** `123123123` */
FINGERPRINT : 'fingerprint'
} ;
/ * *
* How to find the claim inside the proof ' s JSON data
* @ readonly
* @ enum { string }
* /
const ClaimRelation = {
/** Claim is somewhere in the JSON field's textual content */
CONTAINS : 'contains' ,
/** Claim is equal to the JSON field's textual content */
EQUALS : 'equals' ,
/** Claim is equal to an element of the JSON field's array of strings */
ONEOF : 'oneof'
} ;
/ * *
* Status of the Claim instance
* @ readonly
* @ enum { number }
* /
const ClaimStatus = {
/** Claim has been initialized */
INIT : 100 ,
/** Claim has matched its URI to candidate claim definitions */
MATCHED : 101 ,
/** Claim was successfully verified */
VERIFIED : 200 ,
/** Claim was successfully verified using proxied data */
VERIFIED _VIA _PROXY : 201 ,
/** Unknown matching error */
MATCHING _ERROR : 300 ,
/** No matched service providers */
NO _MATCHES : 301 ,
/** Unknown matching error */
VERIFICATION _ERROR : 400 ,
/** No proof found in data returned by service providers */
NO _PROOF _FOUND : 401
} ;
/ * *
* Profile type
* @ readonly
* @ enum { string }
* /
const ProfileType = {
/** ASP profile */
ASP : 'asp' ,
/** OpenPGP profile */
OPENPGP : 'openpgp'
} ;
/ * *
* Public key type
* @ readonly
* @ enum { string }
* /
const PublicKeyType = {
EDDSA : 'eddsa' ,
ES256 : 'es256' ,
OPENPGP : 'openpgp' ,
2023-07-13 02:41:31 -06:00
UNKNOWN : 'unknown' ,
2023-07-09 04:05:21 -06:00
NONE : 'none'
} ;
/ * *
* Public key format
* @ readonly
* @ enum { string }
* /
const PublicKeyEncoding = {
PEM : 'pem' ,
JWK : 'jwk' ,
ARMORED _PGP : 'armored_pgp' ,
NONE : 'none'
} ;
/ * *
* Method to fetch the public key
* @ readonly
* @ enum { string }
* /
const PublicKeyFetchMethod = {
ASPE : 'aspe' ,
HKP : 'hkp' ,
WKD : 'wkd' ,
HTTP : 'http' ,
NONE : 'none'
} ;
var enums = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
ClaimFormat : ClaimFormat ,
ClaimRelation : ClaimRelation ,
ClaimStatus : ClaimStatus ,
EntityEncodingFormat : EntityEncodingFormat ,
Fetcher : Fetcher ,
ProfileType : ProfileType ,
ProofAccessRestriction : ProofAccessRestriction ,
ProofFormat : ProofFormat ,
ProxyPolicy : ProxyPolicy ,
PublicKeyEncoding : PublicKeyEncoding ,
PublicKeyFetchMethod : PublicKeyFetchMethod ,
PublicKeyType : PublicKeyType
} ) ;
var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : { } ;
function getDefaultExportFromCjs ( x ) {
return x && x . _ _esModule && Object . prototype . hasOwnProperty . call ( x , 'default' ) ? x [ 'default' ] : x ;
}
function getAugmentedNamespace ( n ) {
if ( n . _ _esModule ) return n ;
var f = n . default ;
if ( typeof f == "function" ) {
var a = function a ( ) {
if ( this instanceof a ) {
var args = [ null ] ;
args . push . apply ( args , arguments ) ;
var Ctor = Function . bind . apply ( f , args ) ;
return new Ctor ( ) ;
}
return f . apply ( this , arguments ) ;
} ;
a . prototype = f . prototype ;
} else a = { } ;
Object . defineProperty ( a , '__esModule' , { value : true } ) ;
Object . keys ( n ) . forEach ( function ( k ) {
var d = Object . getOwnPropertyDescriptor ( n , k ) ;
Object . defineProperty ( a , k , d . get ? d : {
enumerable : true ,
get : function ( ) {
return n [ k ] ;
}
} ) ;
} ) ;
return a ;
}
var isAlphanumeric$1 = { } ;
var assertString = { exports : { } } ;
( function ( module , exports ) {
Object . defineProperty ( exports , "__esModule" , {
value : true
} ) ;
exports . default = assertString ;
function _typeof ( obj ) { "@babel/helpers - typeof" ; if ( typeof Symbol === "function" && typeof Symbol . iterator === "symbol" ) { _typeof = function _typeof ( obj ) { return typeof obj ; } ; } else { _typeof = function _typeof ( obj ) { return obj && typeof Symbol === "function" && obj . constructor === Symbol && obj !== Symbol . prototype ? "symbol" : typeof obj ; } ; } return _typeof ( obj ) ; }
function assertString ( input ) {
var isString = typeof input === 'string' || input instanceof String ;
if ( ! isString ) {
var invalidType = _typeof ( input ) ;
if ( input === null ) invalidType = 'null' ; else if ( invalidType === 'object' ) invalidType = input . constructor . name ;
throw new TypeError ( "Expected a string but received a " . concat ( invalidType ) ) ;
}
}
module . exports = exports . default ;
module . exports . default = exports . default ;
} ( assertString , assertString . exports ) ) ;
var assertStringExports = assertString . exports ;
var alpha$2 = { } ;
Object . defineProperty ( alpha$2 , "__esModule" , {
value : true
} ) ;
alpha$2 . commaDecimal = alpha$2 . dotDecimal = alpha$2 . bengaliLocales = alpha$2 . farsiLocales = alpha$2 . arabicLocales = alpha$2 . englishLocales = alpha$2 . decimal = alpha$2 . alphanumeric = alpha$2 . alpha = void 0 ;
var alpha$1 = {
'en-US' : /^[A-Z]+$/i ,
'az-AZ' : /^[A-VXYZÇƏĞİı ÖŞÜ]+$/i ,
'bg-BG' : /^[А -Я]+$/i ,
'cs-CZ' : /^[A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]+$/i ,
'da-DK' : /^[A-ZÆØÅ]+$/i ,
'de-DE' : /^[A-ZÄÖÜß]+$/i ,
'el-GR' : /^[Α -ώ]+$/i ,
'es-ES' : /^[A-ZÁÉÍÑÓÚÜ]+$/i ,
'fa-IR' : /^[ابپتثجچحخدذرزژسشصضطظعغفقکگلمنوهی]+$/i ,
'fi-FI' : /^[A-ZÅÄÖ]+$/i ,
'fr-FR' : /^[A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]+$/i ,
'it-IT' : /^[A-ZÀÉÈÌÎÓÒÙ]+$/i ,
'ja-JP' : /^[ぁ-んァ-ヶヲ-゚一-龠ー・。、]+$/i ,
'nb-NO' : /^[A-ZÆØÅ]+$/i ,
'nl-NL' : /^[A-ZÁÉËÏÓÖÜÚ]+$/i ,
'nn-NO' : /^[A-ZÆØÅ]+$/i ,
'hu-HU' : /^[A-ZÁÉÍÓÖŐÚÜŰ]+$/i ,
'pl-PL' : /^[A-ZĄĆĘŚŁŃÓŻŹ]+$/i ,
'pt-PT' : /^[A-ZÃÁÀÂÄÇÉÊËÍÏÕÓÔÖÚÜ]+$/i ,
'ru-RU' : /^[А -ЯЁ]+$/i ,
'sl-SI' : /^[A-ZČĆĐŠŽ]+$/i ,
'sk-SK' : /^[A-ZÁČĎÉÍŇÓŠŤÚÝŽĹŔĽÄÔ]+$/i ,
'sr-RS@latin' : /^[A-ZČĆŽŠĐ]+$/i ,
'sr-RS' : /^[А -ЯЂЈЉЊЋЏ]+$/i ,
'sv-SE' : /^[A-ZÅÄÖ]+$/i ,
'th-TH' : /^[ก-๐ \s]+$/i ,
'tr-TR' : /^[A-ZÇĞİı ÖŞÜ]+$/i ,
'uk-UA' : /^[А -ЩЬ ЮЯЄIЇҐі ]+$/i ,
'vi-VN' : /^[A-ZÀÁẠẢÃÂẦẤẬẨẪĂẰẮẶẲẴĐÈÉẸẺẼÊỀẾỆỂỄÌÍỊỈĨÒÓỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÙÚỤỦŨƯỪỨỰỬỮỲÝỴỶỸ]+$/i ,
'ko-KR' : /^[ㄱ-ㅎㅏ-ㅣ가-힣]*$/ ,
'ku-IQ' : /^[ئابپتجچحخدرڕزژسشعغفڤقکگلڵمنوۆھەیێيطؤثآإأكضصةظذ]+$/i ,
ar : /^[ءآأؤإئابةتثجحخدذرزسشصضطظعغفقكلمنهوىيًٌٍَُِّْٰ]+$/ ,
he : /^[א-ת]+$/ ,
fa : /^['آاءأؤئبپتثجچحخدذرزژسشصضطظعغفقکگلمنوهةی']+$/i ,
bn : /^['ঀঁংঃঅআইঈউঊঋঌএঐওঔকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহ়ঽািীুূৃৄেৈোৌ্ৎৗড়ঢ়য়ৠৡৢৣৰৱ৲৳৴৵৶৷৸৹৺৻']+$/ ,
'hi-IN' : /^[\u0900-\u0961]+[\u0972-\u097F]*$/i ,
'si-LK' : /^[\u0D80-\u0DFF]+$/
} ;
alpha$2 . alpha = alpha$1 ;
var alphanumeric = {
'en-US' : /^[0-9A-Z]+$/i ,
'az-AZ' : /^[0-9A-VXYZÇƏĞİı ÖŞÜ]+$/i ,
'bg-BG' : /^[0-9А -Я]+$/i ,
'cs-CZ' : /^[0-9A-ZÁČĎÉĚÍŇÓŘŠŤÚŮÝŽ]+$/i ,
'da-DK' : /^[0-9A-ZÆØÅ]+$/i ,
'de-DE' : /^[0-9A-ZÄÖÜß]+$/i ,
'el-GR' : /^[0-9Α -ω]+$/i ,
'es-ES' : /^[0-9A-ZÁÉÍÑÓÚÜ]+$/i ,
'fi-FI' : /^[0-9A-ZÅÄÖ]+$/i ,
'fr-FR' : /^[0-9A-ZÀÂÆÇÉÈÊËÏÎÔŒÙÛÜŸ]+$/i ,
'it-IT' : /^[0-9A-ZÀÉÈÌÎÓÒÙ]+$/i ,
'ja-JP' : /^[0-90 -9ぁ-んァ-ヶヲ-゚一-龠ー・。、]+$/i ,
'hu-HU' : /^[0-9A-ZÁÉÍÓÖŐÚÜŰ]+$/i ,
'nb-NO' : /^[0-9A-ZÆØÅ]+$/i ,
'nl-NL' : /^[0-9A-ZÁÉËÏÓÖÜÚ]+$/i ,
'nn-NO' : /^[0-9A-ZÆØÅ]+$/i ,
'pl-PL' : /^[0-9A-ZĄĆĘŚŁŃÓŻŹ]+$/i ,
'pt-PT' : /^[0-9A-ZÃÁÀÂÄÇÉÊËÍÏÕÓÔÖÚÜ]+$/i ,
'ru-RU' : /^[0-9А -ЯЁ]+$/i ,
'sl-SI' : /^[0-9A-ZČĆĐŠŽ]+$/i ,
'sk-SK' : /^[0-9A-ZÁČĎÉÍŇÓŠŤÚÝŽĹŔĽÄÔ]+$/i ,
'sr-RS@latin' : /^[0-9A-ZČĆŽŠĐ]+$/i ,
'sr-RS' : /^[0-9А -ЯЂЈЉЊЋЏ]+$/i ,
'sv-SE' : /^[0-9A-ZÅÄÖ]+$/i ,
'th-TH' : /^[ก-๙\s]+$/i ,
'tr-TR' : /^[0-9A-ZÇĞİı ÖŞÜ]+$/i ,
'uk-UA' : /^[0-9А -ЩЬ ЮЯЄIЇҐі ]+$/i ,
'ko-KR' : /^[0-9ㄱ-ㅎㅏ-ㅣ가-힣]*$/ ,
'ku-IQ' : /^[٠ ١ ٢٣٤٥ ٦٧ ٨٩0-9ئا بپتجچحخدرڕزژسشعغفڤقکگلڵمنوۆھ ە یێيطؤثآإأكضصةظذ]+$/i ,
'vi-VN' : /^[0-9A-ZÀÁẠẢÃÂẦẤẬẨẪĂẰẮẶẲẴĐÈÉẸẺẼÊỀẾỆỂỄÌÍỊỈĨÒÓỌỎÕÔỒỐỘỔỖƠỜỚỢỞỠÙÚỤỦŨƯỪỨỰỬỮỲÝỴỶỸ]+$/i ,
ar : /^[٠ ١ ٢٣٤٥ ٦٧ ٨٩0-9ءآأؤإئا بةتثجحخدذرزسشصضطظعغفقكلمنه وىيًٌٍَُِّْٰ]+$/ ,
he : /^[0-9א-ת]+$/ ,
fa : /^['0-9آا ءأؤئبپتثجچحخدذرزژسشصضطظعغفقکگلمنوه ةی۱ ۲۳۴۵ ۶۷ ۸۹۰ ']+$/i ,
bn : /^['ঀঁংঃঅআইঈউঊঋঌএঐওঔকখগঘঙচছজঝঞটঠডঢণতথদধনপফবভমযরলশষসহ়ঽািীুূৃৄেৈোৌ্ৎৗড়ঢ়য়ৠৡৢৣ০১২৩৪৫৬৭৮৯ৰৱ৲৳৴৵৶৷৸৹৺৻']+$/ ,
'hi-IN' : /^[\u0900-\u0963]+[\u0966-\u097F]*$/i ,
'si-LK' : /^[0-9\u0D80-\u0DFF]+$/
} ;
alpha$2 . alphanumeric = alphanumeric ;
var decimal = {
'en-US' : '.' ,
ar : '٫ '
} ;
alpha$2 . decimal = decimal ;
var englishLocales = [ 'AU' , 'GB' , 'HK' , 'IN' , 'NZ' , 'ZA' , 'ZM' ] ;
alpha$2 . englishLocales = englishLocales ;
for ( var locale , i = 0 ; i < englishLocales . length ; i ++ ) {
locale = "en-" . concat ( englishLocales [ i ] ) ;
alpha$1 [ locale ] = alpha$1 [ 'en-US' ] ;
alphanumeric [ locale ] = alphanumeric [ 'en-US' ] ;
decimal [ locale ] = decimal [ 'en-US' ] ;
} // Source: http://www.localeplanet.com/java/
var arabicLocales = [ 'AE' , 'BH' , 'DZ' , 'EG' , 'IQ' , 'JO' , 'KW' , 'LB' , 'LY' , 'MA' , 'QM' , 'QA' , 'SA' , 'SD' , 'SY' , 'TN' , 'YE' ] ;
alpha$2 . arabicLocales = arabicLocales ;
for ( var _locale , _i = 0 ; _i < arabicLocales . length ; _i ++ ) {
_locale = "ar-" . concat ( arabicLocales [ _i ] ) ;
alpha$1 [ _locale ] = alpha$1 . ar ;
alphanumeric [ _locale ] = alphanumeric . ar ;
decimal [ _locale ] = decimal . ar ;
}
var farsiLocales = [ 'IR' , 'AF' ] ;
alpha$2 . farsiLocales = farsiLocales ;
for ( var _locale2 , _i2 = 0 ; _i2 < farsiLocales . length ; _i2 ++ ) {
_locale2 = "fa-" . concat ( farsiLocales [ _i2 ] ) ;
alphanumeric [ _locale2 ] = alphanumeric . fa ;
decimal [ _locale2 ] = decimal . ar ;
}
var bengaliLocales = [ 'BD' , 'IN' ] ;
alpha$2 . bengaliLocales = bengaliLocales ;
for ( var _locale3 , _i3 = 0 ; _i3 < bengaliLocales . length ; _i3 ++ ) {
_locale3 = "bn-" . concat ( bengaliLocales [ _i3 ] ) ;
alpha$1 [ _locale3 ] = alpha$1 . bn ;
alphanumeric [ _locale3 ] = alphanumeric . bn ;
decimal [ _locale3 ] = decimal [ 'en-US' ] ;
} // Source: https://en.wikipedia.org/wiki/Decimal_mark
var dotDecimal = [ 'ar-EG' , 'ar-LB' , 'ar-LY' ] ;
alpha$2 . dotDecimal = dotDecimal ;
var commaDecimal = [ 'bg-BG' , 'cs-CZ' , 'da-DK' , 'de-DE' , 'el-GR' , 'en-ZM' , 'es-ES' , 'fr-CA' , 'fr-FR' , 'id-ID' , 'it-IT' , 'ku-IQ' , 'hi-IN' , 'hu-HU' , 'nb-NO' , 'nn-NO' , 'nl-NL' , 'pl-PL' , 'pt-PT' , 'ru-RU' , 'si-LK' , 'sl-SI' , 'sr-RS@latin' , 'sr-RS' , 'sv-SE' , 'tr-TR' , 'uk-UA' , 'vi-VN' ] ;
alpha$2 . commaDecimal = commaDecimal ;
for ( var _i4 = 0 ; _i4 < dotDecimal . length ; _i4 ++ ) {
decimal [ dotDecimal [ _i4 ] ] = decimal [ 'en-US' ] ;
}
for ( var _i5 = 0 ; _i5 < commaDecimal . length ; _i5 ++ ) {
decimal [ commaDecimal [ _i5 ] ] = ',' ;
}
alpha$1 [ 'fr-CA' ] = alpha$1 [ 'fr-FR' ] ;
alphanumeric [ 'fr-CA' ] = alphanumeric [ 'fr-FR' ] ;
alpha$1 [ 'pt-BR' ] = alpha$1 [ 'pt-PT' ] ;
alphanumeric [ 'pt-BR' ] = alphanumeric [ 'pt-PT' ] ;
decimal [ 'pt-BR' ] = decimal [ 'pt-PT' ] ; // see #862
alpha$1 [ 'pl-Pl' ] = alpha$1 [ 'pl-PL' ] ;
alphanumeric [ 'pl-Pl' ] = alphanumeric [ 'pl-PL' ] ;
decimal [ 'pl-Pl' ] = decimal [ 'pl-PL' ] ; // see #1455
alpha$1 [ 'fa-AF' ] = alpha$1 . fa ;
Object . defineProperty ( isAlphanumeric$1 , "__esModule" , {
value : true
} ) ;
var _default = isAlphanumeric$1 . default = isAlphanumeric ;
isAlphanumeric$1 . locales = void 0 ;
var _assertString = _interopRequireDefault ( assertStringExports ) ;
var _alpha = alpha$2 ;
function _interopRequireDefault ( obj ) { return obj && obj . _ _esModule ? obj : { default : obj } ; }
function isAlphanumeric ( _str ) {
var locale = arguments . length > 1 && arguments [ 1 ] !== undefined ? arguments [ 1 ] : 'en-US' ;
var options = arguments . length > 2 && arguments [ 2 ] !== undefined ? arguments [ 2 ] : { } ;
( 0 , _assertString . default ) ( _str ) ;
var str = _str ;
var ignore = options . ignore ;
if ( ignore ) {
if ( ignore instanceof RegExp ) {
str = str . replace ( ignore , '' ) ;
} else if ( typeof ignore === 'string' ) {
str = str . replace ( new RegExp ( "[" . concat ( ignore . replace ( /[-[\]{}()*+?.,\\^$|#\\s]/g , '\\$&' ) , "]" ) , 'g' ) , '' ) ; // escape regex for ignore
} else {
throw new Error ( 'ignore should be instance of a String or RegExp' ) ;
}
}
if ( locale in _alpha . alphanumeric ) {
return _alpha . alphanumeric [ locale ] . test ( str ) ;
}
throw new Error ( "Invalid locale '" . concat ( locale , "'" ) ) ;
}
var locales = Object . keys ( _alpha . alphanumeric ) ;
isAlphanumeric$1 . locales = locales ;
var validUrl = { exports : { } } ;
( function ( module ) {
( function ( module ) {
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 ) ;
} ( validUrl ) ) ;
var validUrlExports = validUrl . exports ;
var isPlainObj = value => {
if ( Object . prototype . toString . call ( value ) !== '[object Object]' ) {
return false ;
}
const prototype = Object . getPrototypeOf ( value ) ;
return prototype === null || prototype === Object . prototype ;
} ;
const isOptionObject = isPlainObj ;
const { hasOwnProperty } = Object . prototype ;
const { propertyIsEnumerable } = Object ;
const defineProperty = ( object , name , value ) => Object . defineProperty ( object , name , {
value ,
writable : true ,
enumerable : true ,
configurable : true
} ) ;
const globalThis$1 = commonjsGlobal ;
const defaultMergeOptions = {
concatArrays : false ,
ignoreUndefined : false
} ;
const getEnumerableOwnPropertyKeys = value => {
const keys = [ ] ;
for ( const key in value ) {
if ( hasOwnProperty . call ( value , key ) ) {
keys . push ( key ) ;
}
}
/* istanbul ignore else */
if ( Object . getOwnPropertySymbols ) {
const symbols = Object . getOwnPropertySymbols ( value ) ;
for ( const symbol of symbols ) {
if ( propertyIsEnumerable . call ( value , symbol ) ) {
keys . push ( symbol ) ;
}
}
}
return keys ;
} ;
function clone ( value ) {
if ( Array . isArray ( value ) ) {
return cloneArray ( value ) ;
}
if ( isOptionObject ( value ) ) {
return cloneOptionObject ( value ) ;
}
return value ;
}
function cloneArray ( array ) {
const result = array . slice ( 0 , 0 ) ;
getEnumerableOwnPropertyKeys ( array ) . forEach ( key => {
defineProperty ( result , key , clone ( array [ key ] ) ) ;
} ) ;
return result ;
}
function cloneOptionObject ( object ) {
const result = Object . getPrototypeOf ( object ) === null ? Object . create ( null ) : { } ;
getEnumerableOwnPropertyKeys ( object ) . forEach ( key => {
defineProperty ( result , key , clone ( object [ key ] ) ) ;
} ) ;
return result ;
}
/ * *
* @ 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$2 ( merged [ key ] , source [ key ] , config ) ) ;
} else {
defineProperty ( merged , key , clone ( source [ key ] ) ) ;
}
} ) ;
return merged ;
} ;
/ * *
* @ 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 ;
} ;
/ * *
* @ param { * } merged already cloned
* @ param { * } source something to merge
* @ param { Object } config Config Object
* @ returns { * } cloned Object
* /
function merge$2 ( 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 ) ;
}
var mergeOptions = function ( ... options ) {
const config = merge$2 ( clone ( defaultMergeOptions ) , ( this !== globalThis$1 && this ) || { } , defaultMergeOptions ) ;
let merged = { _ : { } } ;
for ( const option of options ) {
if ( option === undefined ) {
continue ;
}
if ( ! isOptionObject ( option ) ) {
throw new TypeError ( '`' + option + '` is not an Option Object' ) ;
}
merged = merge$2 ( merged , { _ : option } , config ) ;
}
return merged . _ ;
} ;
var mergeOptions$1 = /*@__PURE__*/ getDefaultExportFromCjs ( mergeOptions ) ;
var global$1 = ( typeof global !== "undefined" ? global :
typeof self !== "undefined" ? self :
typeof window !== "undefined" ? window : { } ) ;
// shim for using process in browser
// based off https://github.com/defunctzombie/node-process/blob/master/browser.js
function defaultSetTimout ( ) {
throw new Error ( 'setTimeout has not been defined' ) ;
}
function defaultClearTimeout ( ) {
throw new Error ( 'clearTimeout has not been defined' ) ;
}
var cachedSetTimeout = defaultSetTimout ;
var cachedClearTimeout = defaultClearTimeout ;
if ( typeof global$1 . setTimeout === 'function' ) {
cachedSetTimeout = setTimeout ;
}
if ( typeof global$1 . clearTimeout === 'function' ) {
cachedClearTimeout = clearTimeout ;
}
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 ) ;
}
function nextTick ( 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 ) ;
} ;
var title = 'browser' ;
var platform = 'browser' ;
var browser = true ;
var env = { } ;
var argv = [ ] ;
var version = '' ; // empty string to avoid regexp issues
var versions = { } ;
var release = { } ;
var config = { } ;
function noop ( ) { }
var on = noop ;
var addListener = noop ;
var once = noop ;
var off = noop ;
var removeListener = noop ;
var removeAllListeners = noop ;
var emit = noop ;
function binding ( name ) {
throw new Error ( 'process.binding is not supported' ) ;
}
function cwd ( ) { return '/' }
function chdir ( dir ) {
throw new Error ( 'process.chdir is not supported' ) ;
} function umask ( ) { return 0 ; }
// from https://github.com/kumavis/browser-process-hrtime/blob/master/index.js
var performance = global$1 . performance || { } ;
var performanceNow =
performance . now ||
performance . mozNow ||
performance . msNow ||
performance . oNow ||
performance . webkitNow ||
function ( ) { return ( new Date ( ) ) . getTime ( ) } ;
// generate timestamp or delta
// see http://nodejs.org/api/process.html#process_process_hrtime
function hrtime ( previousTimestamp ) {
var clocktime = performanceNow . call ( performance ) * 1e-3 ;
var seconds = Math . floor ( clocktime ) ;
var nanoseconds = Math . floor ( ( clocktime % 1 ) * 1e9 ) ;
if ( previousTimestamp ) {
seconds = seconds - previousTimestamp [ 0 ] ;
nanoseconds = nanoseconds - previousTimestamp [ 1 ] ;
if ( nanoseconds < 0 ) {
seconds -- ;
nanoseconds += 1e9 ;
}
}
return [ seconds , nanoseconds ]
}
var startTime = new Date ( ) ;
function uptime ( ) {
var currentTime = new Date ( ) ;
var dif = currentTime - startTime ;
return dif / 1000 ;
}
var browser$1 = {
nextTick : nextTick ,
title : title ,
browser : browser ,
env : env ,
argv : argv ,
version : version ,
versions : versions ,
on : on ,
addListener : addListener ,
once : once ,
off : off ,
removeListener : removeListener ,
removeAllListeners : removeAllListeners ,
emit : emit ,
binding : binding ,
cwd : cwd ,
chdir : chdir ,
umask : umask ,
hrtime : hrtime ,
platform : platform ,
release : release ,
config : config ,
uptime : uptime
} ;
var lib$1 = { } ;
Object . defineProperty ( lib$1 , "__esModule" , {
value : true
} ) ;
var _typeof = typeof Symbol === "function" && typeof Symbol . iterator === "symbol" ? function ( obj ) { return typeof obj ; } : function ( obj ) { return obj && typeof Symbol === "function" && obj . constructor === Symbol && obj !== Symbol . prototype ? "symbol" : typeof obj ; } ;
/* global window self */
var isBrowser = typeof window !== 'undefined' && typeof window . document !== 'undefined' ;
/* eslint-disable no-restricted-globals */
var isWebWorker = ( typeof self === 'undefined' ? 'undefined' : _typeof ( self ) ) === 'object' && self . constructor && self . constructor . name === 'DedicatedWorkerGlobalScope' ;
/* eslint-enable no-restricted-globals */
var isNode = typeof browser$1 !== 'undefined' && browser$1 . versions != null && browser$1 . versions . node != null ;
/ * *
* @ see https : //github.com/jsdom/jsdom/releases/tag/12.0.0
* @ see https : //github.com/jsdom/jsdom/issues/1537
* /
/* eslint-disable no-undef */
var isJsDom = function isJsDom ( ) {
return typeof window !== 'undefined' && window . name === 'nodejs' || navigator . userAgent . includes ( 'Node.js' ) || navigator . userAgent . includes ( 'jsdom' ) ;
} ;
lib$1 . isBrowser = isBrowser ;
lib$1 . isWebWorker = isWebWorker ;
var isNode _1 = lib$1 . isNode = isNode ;
lib$1 . isJsDom = isJsDom ;
var isFQDN$1 = { exports : { } } ;
var merge$1 = { exports : { } } ;
( function ( module , exports ) {
Object . defineProperty ( exports , "__esModule" , {
value : true
} ) ;
exports . default = merge ;
function merge ( ) {
var obj = arguments . length > 0 && arguments [ 0 ] !== undefined ? arguments [ 0 ] : { } ;
var defaults = arguments . length > 1 ? arguments [ 1 ] : undefined ;
for ( var key in defaults ) {
if ( typeof obj [ key ] === 'undefined' ) {
obj [ key ] = defaults [ key ] ;
}
}
return obj ;
}
module . exports = exports . default ;
module . exports . default = exports . default ;
} ( merge$1 , merge$1 . exports ) ) ;
var mergeExports = merge$1 . exports ;
( function ( module , exports ) {
2023-07-08 00:36:57 -06:00
2023-07-09 04:05:21 -06:00
Object . defineProperty ( exports , "__esModule" , {
value : true
} ) ;
exports . default = isFQDN ;
2023-07-08 00:36:57 -06:00
2023-07-09 04:05:21 -06:00
var _assertString = _interopRequireDefault ( assertStringExports ) ;
2023-07-08 00:36:57 -06:00
2023-07-09 04:05:21 -06:00
var _merge = _interopRequireDefault ( mergeExports ) ;
2023-07-08 00:36:57 -06:00
2023-07-09 04:05:21 -06:00
function _interopRequireDefault ( obj ) { return obj && obj . _ _esModule ? obj : { default : obj } ; }
2023-07-08 00:36:57 -06:00
2023-07-09 04:05:21 -06:00
var default _fqdn _options = {
require _tld : true ,
allow _underscores : false ,
allow _trailing _dot : false ,
allow _numeric _tld : false ,
allow _wildcard : false ,
ignore _max _length : false
} ;
2023-07-08 00:36:57 -06:00
2023-07-09 04:05:21 -06:00
function isFQDN ( str , options ) {
( 0 , _assertString . default ) ( str ) ;
options = ( 0 , _merge . default ) ( options , default _fqdn _options ) ;
/* Remove the optional trailing dot before checking validity */
2023-07-08 00:36:57 -06:00
2023-07-09 04:05:21 -06:00
if ( options . allow _trailing _dot && str [ str . length - 1 ] === '.' ) {
str = str . substring ( 0 , str . length - 1 ) ;
}
/* Remove the optional wildcard before checking validity */
2023-07-08 00:36:57 -06:00
2023-07-09 04:05:21 -06:00
if ( options . allow _wildcard === true && str . indexOf ( '*.' ) === 0 ) {
str = str . substring ( 2 ) ;
}
2023-07-08 00:36:57 -06:00
2023-07-09 04:05:21 -06:00
var parts = str . split ( '.' ) ;
var tld = parts [ parts . length - 1 ] ;
if ( options . require _tld ) {
// disallow fqdns without tld
if ( parts . length < 2 ) {
return false ;
}
if ( ! options . allow _numeric _tld && ! /^([a-z\u00A1-\u00A8\u00AA-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]{2,}|xn[a-z0-9-]{2,})$/i . test ( tld ) ) {
return false ;
} // disallow spaces
if ( /\s/ . test ( tld ) ) {
return false ;
}
} // reject numeric TLDs
if ( ! options . allow _numeric _tld && /^\d+$/ . test ( tld ) ) {
return false ;
}
return parts . every ( function ( part ) {
if ( part . length > 63 && ! options . ignore _max _length ) {
return false ;
}
if ( ! /^[a-z_\u00a1-\uffff0-9-]+$/i . test ( part ) ) {
return false ;
} // disallow full-width chars
if ( /[\uff01-\uff5e]/ . test ( part ) ) {
return false ;
} // disallow parts starting or ending with hyphen
if ( /^-|-$/ . test ( part ) ) {
return false ;
}
if ( ! options . allow _underscores && /_/ . test ( part ) ) {
return false ;
}
return true ;
} ) ;
}
module . exports = exports . default ;
module . exports . default = exports . default ;
} ( isFQDN$1 , isFQDN$1 . exports ) ) ;
var isFQDNExports = isFQDN$1 . exports ;
var isFQDN = /*@__PURE__*/ getDefaultExportFromCjs ( isFQDNExports ) ;
/ *
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
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 .
* /
/ * *
* @ module utils
* /
/ * *
* Generate an URL to request data from a proxy server
* @ param { string } type - The name of the fetcher the proxy must use
* @ param { object } data - The data the proxy must provide to the fetcher
* @ param { object } opts - Options to enable the request
* @ param { object } opts . proxy - Proxy related options
* @ param { object } opts . proxy . scheme - The scheme used by the proxy server
* @ param { object } opts . proxy . hostname - The hostname of the proxy server
* @ returns { string }
* /
function generateProxyURL ( type , data , opts ) {
try {
isFQDN ( opts . proxy . hostname ) ;
} catch ( err ) {
throw new Error ( 'Invalid proxy hostname' )
}
const queryStrings = [ ] ;
Object . keys ( data ) . forEach ( ( key ) => {
queryStrings . push ( ` ${ key } = ${ encodeURIComponent ( data [ key ] ) } ` ) ;
} ) ;
const scheme = opts . proxy . scheme ? opts . proxy . scheme : 'https' ;
2023-07-13 02:41:31 -06:00
return ` ${ scheme } :// ${ opts . proxy . hostname } /api/3/get/ ${ type } ? ${ queryStrings . join (
2023-07-08 00:36:57 -06:00
'&'
) } `
2023-07-09 04:05:21 -06:00
}
/ * *
* Generate the string that must be found in the proof to verify a claim
* @ param { string } fingerprint - The fingerprint of the claim
* @ param { string } format - The claim ' s format ( see { @ link module : enums ~ ClaimFormat | enums . ClaimFormat } )
* @ returns { string }
* /
function generateClaim ( fingerprint , format ) {
switch ( format ) {
case ClaimFormat . URI :
if ( fingerprint . match ( /^(openpgp4fpr|aspe):/ ) ) {
return fingerprint
}
return ` openpgp4fpr: ${ fingerprint } `
case ClaimFormat . FINGERPRINT :
return fingerprint
default :
throw new Error ( 'No valid claim format' )
}
}
/ * *
* Get the URIs from a string and return them as an array
* @ param { string } text - The text that may contain URIs
* @ returns { Array < string > }
* /
function getUriFromString ( text ) {
const re = /((([A-Za-z0-9]+:(?:\/\/)?)(?:[-;:&=+$,\w]+@)?[A-Za-z0-9.-]+|(?:www\.|[-;:&=+$,\w]+@)[A-Za-z0-9.-]+)((?:\/[+~%/.\w\-_]*)?\??(?:[-+=&;%@.\w_]*)#?(?:[.!/\\\w]*))?)/gi ;
const res = text . match ( re ) ;
const urls = [ ] ;
if ( ! res ) {
return [ ]
}
res . forEach ( url => {
// Remove bad trailing characters
let hasBadTrailingChars = true ;
while ( hasBadTrailingChars ) {
const lastChar = url . charAt ( url . length - 1 ) ;
if ( '?!.' . indexOf ( lastChar ) === - 1 ) {
hasBadTrailingChars = false ;
continue
}
url = url . substring ( 0 , url . length - 1 ) ;
}
urls . push ( url ) ;
} ) ;
return urls
}
var utils$9 = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
generateClaim : generateClaim ,
generateProxyURL : generateProxyURL ,
getUriFromString : getUriFromString
} ) ;
/ *
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
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 .
* /
/ * *
* @ module proofs
* /
/ * *
* Delegate the proof request to the correct fetcher .
* This method uses the current environment ( browser / node ) , certain values from
* the ` data ` parameter and the proxy policy set in the ` opts ` parameter to
* choose the right approach to fetch the proof . An error will be thrown if no
* approach is possible .
* @ async
* @ param { import ( './serviceProvider.js' ) . ServiceProvider } data - Data from a claim definition
* @ param { object } opts - Options to enable the request
* @ returns { Promise < object | string > }
* /
async function fetch$2 ( data , opts ) {
if ( isNode _1 ) {
return handleNodeRequests ( data , opts )
}
return handleBrowserRequests ( data , opts )
}
/ * *
* @ param { import ( './serviceProvider.js' ) . ServiceProvider } data - Data from a claim definition
* @ param { object } opts - Options to enable the request
* @ returns { Promise < object | string > }
* /
const handleBrowserRequests = ( data , opts ) => {
switch ( opts . proxy . policy ) {
case ProxyPolicy . ALWAYS :
return createProxyRequestPromise ( data , opts )
case ProxyPolicy . NEVER :
2023-07-13 02:41:31 -06:00
switch ( data . proof . request . accessRestriction ) {
2023-07-09 04:05:21 -06:00
case ProofAccessRestriction . NONE :
case ProofAccessRestriction . GRANTED :
return createDefaultRequestPromise ( data , opts )
case ProofAccessRestriction . NOCORS :
case ProofAccessRestriction . SERVER :
throw new Error (
'Impossible to fetch proof (bad combination of service access and proxy policy)'
)
default :
throw new Error ( 'Invalid proof access value' )
}
case ProxyPolicy . ADAPTIVE :
2023-07-13 02:41:31 -06:00
switch ( data . proof . request . accessRestriction ) {
2023-07-09 04:05:21 -06:00
case ProofAccessRestriction . NONE :
return createFallbackRequestPromise ( data , opts )
case ProofAccessRestriction . NOCORS :
return createProxyRequestPromise ( data , opts )
case ProofAccessRestriction . GRANTED :
return createFallbackRequestPromise ( data , opts )
case ProofAccessRestriction . SERVER :
return createProxyRequestPromise ( data , opts )
default :
throw new Error ( 'Invalid proof access value' )
}
default :
throw new Error ( 'Invalid proxy policy' )
}
} ;
/ * *
* @ param { import ( './serviceProvider.js' ) . ServiceProvider } data - Data from a claim definition
* @ param { object } opts - Options to enable the request
* @ returns { Promise < object | string > }
* /
const handleNodeRequests = ( data , opts ) => {
switch ( opts . proxy . policy ) {
case ProxyPolicy . ALWAYS :
return createProxyRequestPromise ( data , opts )
case ProxyPolicy . NEVER :
return createDefaultRequestPromise ( data , opts )
case ProxyPolicy . ADAPTIVE :
return createFallbackRequestPromise ( data , opts )
default :
throw new Error ( 'Invalid proxy policy' )
}
} ;
/ * *
* @ param { import ( './serviceProvider.js' ) . ServiceProvider } data - Data from a claim definition
* @ param { object } opts - Options to enable the request
* @ returns { Promise < object | string > }
* /
const createDefaultRequestPromise = ( data , opts ) => {
return new Promise ( ( resolve , reject ) => {
2023-07-10 03:46:53 -06:00
if ( ! ( data . proof . request . fetcher in fetcher _ _namespace ) ) {
reject ( new Error ( ` fetcher for ${ data . proof . request . fetcher } not found ` ) ) ;
}
fetcher _ _namespace [ data . proof . request . fetcher ]
2023-07-09 04:05:21 -06:00
. fn ( data . proof . request . data , opts )
. then ( ( res ) => {
return resolve ( {
2023-07-10 03:46:53 -06:00
fetcher : data . proof . request . fetcher ,
2023-07-09 04:05:21 -06:00
data ,
viaProxy : false ,
result : res
} )
} )
. catch ( ( err ) => {
return reject ( err )
} ) ;
} )
} ;
/ * *
* @ param { import ( './serviceProvider.js' ) . ServiceProvider } data - Data from a claim definition
* @ param { object } opts - Options to enable the request
* @ returns { Promise < object | string > }
* /
const createProxyRequestPromise = ( data , opts ) => {
return new Promise ( ( resolve , reject ) => {
let proxyUrl ;
try {
proxyUrl = generateProxyURL (
2023-07-10 03:46:53 -06:00
data . proof . request . fetcher ,
2023-07-09 04:05:21 -06:00
data . proof . request . data ,
opts
) ;
} catch ( err ) {
reject ( err ) ;
}
const requestData = {
url : proxyUrl ,
2023-07-13 02:41:31 -06:00
format : data . proof . response . format ,
fetcherTimeout : data . proof . request . fetcher in fetcher _ _namespace ? fetcher _ _namespace [ data . proof . request . fetcher ] . timeout : 30000
2023-07-09 04:05:21 -06:00
} ;
fetcher _ _namespace . http
. fn ( requestData , opts )
. then ( ( res ) => {
return resolve ( {
2023-07-10 03:46:53 -06:00
fetcher : 'http' ,
2023-07-09 04:05:21 -06:00
data ,
viaProxy : true ,
result : res
} )
} )
. catch ( ( err ) => {
return reject ( err )
} ) ;
} )
} ;
/ * *
* @ param { import ( './serviceProvider.js' ) . ServiceProvider } data - Data from a claim definition
* @ param { object } opts - Options to enable the request
* @ returns { Promise < object | string > }
* /
const createFallbackRequestPromise = ( data , opts ) => {
return new Promise ( ( resolve , reject ) => {
createDefaultRequestPromise ( data , opts )
. then ( ( res ) => {
return resolve ( res )
} )
. catch ( ( err1 ) => {
createProxyRequestPromise ( data , opts )
. then ( ( res ) => {
return resolve ( res )
} )
. catch ( ( err2 ) => {
return reject ( err2 )
} ) ;
} ) ;
} )
} ;
var proofs = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
fetch : fetch$2
} ) ;
/ * !
* hash - wasm ( https : //www.npmjs.com/package/hash-wasm)
* ( c ) Dani Biro
* @ license MIT
* /
/ * ! * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Copyright ( c ) Microsoft Corporation .
2023-07-08 00:36:57 -06:00
2023-07-09 04:05:21 -06:00
Permission to use , copy , modify , and / or distribute this software for any
purpose with or without fee is hereby granted .
2023-07-08 00:36:57 -06:00
2023-07-09 04:05:21 -06:00
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
AND FITNESS . IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL , DIRECT ,
INDIRECT , OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
LOSS OF USE , DATA OR PROFITS , WHETHER IN AN ACTION OF CONTRACT , NEGLIGENCE OR
OTHER TORTIOUS ACTION , ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2023-07-08 00:36:57 -06:00
2023-07-09 04:05:21 -06:00
function _ _awaiter ( thisArg , _arguments , P , generator ) {
function adopt ( value ) { return value instanceof P ? value : new P ( function ( resolve ) { resolve ( value ) ; } ) ; }
return new ( P || ( P = Promise ) ) ( function ( resolve , reject ) {
function fulfilled ( value ) { try { step ( generator . next ( value ) ) ; } catch ( e ) { reject ( e ) ; } }
function rejected ( value ) { try { step ( generator [ "throw" ] ( value ) ) ; } catch ( e ) { reject ( e ) ; } }
function step ( result ) { result . done ? resolve ( result . value ) : adopt ( result . value ) . then ( fulfilled , rejected ) ; }
step ( ( generator = generator . apply ( thisArg , _arguments || [ ] ) ) . next ( ) ) ;
} ) ;
}
class Mutex {
constructor ( ) {
this . mutex = Promise . resolve ( ) ;
}
lock ( ) {
let begin = ( ) => { } ;
this . mutex = this . mutex . then ( ( ) => new Promise ( begin ) ) ;
return new Promise ( ( res ) => {
begin = res ;
} ) ;
}
dispatch ( fn ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
const unlock = yield this . lock ( ) ;
try {
return yield Promise . resolve ( fn ( ) ) ;
}
finally {
unlock ( ) ;
}
} ) ;
}
}
/* eslint-disable import/prefer-default-export */
/* eslint-disable no-bitwise */
var _a$1 ;
function getGlobal ( ) {
if ( typeof globalThis !== 'undefined' )
return globalThis ;
// eslint-disable-next-line no-restricted-globals
if ( typeof self !== 'undefined' )
return self ;
if ( typeof window !== 'undefined' )
return window ;
return global$1 ;
}
const globalObject = getGlobal ( ) ;
const nodeBuffer = ( _a$1 = globalObject . Buffer ) !== null && _a$1 !== void 0 ? _a$1 : null ;
const textEncoder = globalObject . TextEncoder ? new globalObject . TextEncoder ( ) : null ;
function hexCharCodesToInt ( a , b ) {
return ( ( ( a & 0xF ) + ( ( a >> 6 ) | ( ( a >> 3 ) & 0x8 ) ) ) << 4 ) | ( ( b & 0xF ) + ( ( b >> 6 ) | ( ( b >> 3 ) & 0x8 ) ) ) ;
}
function writeHexToUInt8 ( buf , str ) {
const size = str . length >> 1 ;
for ( let i = 0 ; i < size ; i ++ ) {
const index = i << 1 ;
buf [ i ] = hexCharCodesToInt ( str . charCodeAt ( index ) , str . charCodeAt ( index + 1 ) ) ;
}
}
function hexStringEqualsUInt8 ( str , buf ) {
if ( str . length !== buf . length * 2 ) {
return false ;
}
for ( let i = 0 ; i < buf . length ; i ++ ) {
const strIndex = i << 1 ;
if ( buf [ i ] !== hexCharCodesToInt ( str . charCodeAt ( strIndex ) , str . charCodeAt ( strIndex + 1 ) ) ) {
return false ;
}
}
return true ;
}
const alpha = 'a' . charCodeAt ( 0 ) - 10 ;
const digit = '0' . charCodeAt ( 0 ) ;
function getDigestHex ( tmpBuffer , input , hashLength ) {
let p = 0 ;
/* eslint-disable no-plusplus */
for ( let i = 0 ; i < hashLength ; i ++ ) {
let nibble = input [ i ] >>> 4 ;
tmpBuffer [ p ++ ] = nibble > 9 ? nibble + alpha : nibble + digit ;
nibble = input [ i ] & 0xF ;
tmpBuffer [ p ++ ] = nibble > 9 ? nibble + alpha : nibble + digit ;
}
/* eslint-enable no-plusplus */
return String . fromCharCode . apply ( null , tmpBuffer ) ;
}
const getUInt8Buffer = nodeBuffer !== null
? ( data ) => {
if ( typeof data === 'string' ) {
const buf = nodeBuffer . from ( data , 'utf8' ) ;
return new Uint8Array ( buf . buffer , buf . byteOffset , buf . length ) ;
}
if ( nodeBuffer . isBuffer ( data ) ) {
return new Uint8Array ( data . buffer , data . byteOffset , data . length ) ;
}
if ( ArrayBuffer . isView ( data ) ) {
return new Uint8Array ( data . buffer , data . byteOffset , data . byteLength ) ;
}
throw new Error ( 'Invalid data type!' ) ;
}
: ( data ) => {
if ( typeof data === 'string' ) {
return textEncoder . encode ( data ) ;
}
if ( ArrayBuffer . isView ( data ) ) {
return new Uint8Array ( data . buffer , data . byteOffset , data . byteLength ) ;
}
throw new Error ( 'Invalid data type!' ) ;
} ;
const base64Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' ;
const base64Lookup = new Uint8Array ( 256 ) ;
for ( let i = 0 ; i < base64Chars . length ; i ++ ) {
base64Lookup [ base64Chars . charCodeAt ( i ) ] = i ;
}
function encodeBase64$1 ( data , pad = true ) {
const len = data . length ;
const extraBytes = len % 3 ;
const parts = [ ] ;
const len2 = len - extraBytes ;
for ( let i = 0 ; i < len2 ; i += 3 ) {
const tmp = ( ( data [ i ] << 16 ) & 0xFF0000 )
+ ( ( data [ i + 1 ] << 8 ) & 0xFF00 )
+ ( data [ i + 2 ] & 0xFF ) ;
const triplet = base64Chars . charAt ( ( tmp >> 18 ) & 0x3F )
+ base64Chars . charAt ( ( tmp >> 12 ) & 0x3F )
+ base64Chars . charAt ( ( tmp >> 6 ) & 0x3F )
+ base64Chars . charAt ( tmp & 0x3F ) ;
parts . push ( triplet ) ;
}
if ( extraBytes === 1 ) {
const tmp = data [ len - 1 ] ;
const a = base64Chars . charAt ( tmp >> 2 ) ;
const b = base64Chars . charAt ( ( tmp << 4 ) & 0x3F ) ;
parts . push ( ` ${ a } ${ b } ` ) ;
if ( pad ) {
parts . push ( '==' ) ;
}
}
else if ( extraBytes === 2 ) {
const tmp = ( data [ len - 2 ] << 8 ) + data [ len - 1 ] ;
const a = base64Chars . charAt ( tmp >> 10 ) ;
const b = base64Chars . charAt ( ( tmp >> 4 ) & 0x3F ) ;
const c = base64Chars . charAt ( ( tmp << 2 ) & 0x3F ) ;
parts . push ( ` ${ a } ${ b } ${ c } ` ) ;
if ( pad ) {
parts . push ( '=' ) ;
}
}
return parts . join ( '' ) ;
}
function getDecodeBase64Length ( data ) {
let bufferLength = Math . floor ( data . length * 0.75 ) ;
const len = data . length ;
if ( data [ len - 1 ] === '=' ) {
bufferLength -= 1 ;
if ( data [ len - 2 ] === '=' ) {
bufferLength -= 1 ;
}
}
return bufferLength ;
}
function decodeBase64$1 ( data ) {
const bufferLength = getDecodeBase64Length ( data ) ;
const len = data . length ;
const bytes = new Uint8Array ( bufferLength ) ;
let p = 0 ;
for ( let i = 0 ; i < len ; i += 4 ) {
const encoded1 = base64Lookup [ data . charCodeAt ( i ) ] ;
const encoded2 = base64Lookup [ data . charCodeAt ( i + 1 ) ] ;
const encoded3 = base64Lookup [ data . charCodeAt ( i + 2 ) ] ;
const encoded4 = base64Lookup [ data . charCodeAt ( i + 3 ) ] ;
bytes [ p ] = ( encoded1 << 2 ) | ( encoded2 >> 4 ) ;
p += 1 ;
bytes [ p ] = ( ( encoded2 & 15 ) << 4 ) | ( encoded3 >> 2 ) ;
p += 1 ;
bytes [ p ] = ( ( encoded3 & 3 ) << 6 ) | ( encoded4 & 63 ) ;
p += 1 ;
}
return bytes ;
}
const MAX _HEAP = 16 * 1024 ;
const WASM _FUNC _HASH _LENGTH = 4 ;
const wasmMutex = new Mutex ( ) ;
const wasmModuleCache = new Map ( ) ;
function WASMInterface ( binary , hashLength ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
let wasmInstance = null ;
let memoryView = null ;
let initialized = false ;
if ( typeof WebAssembly === 'undefined' ) {
throw new Error ( 'WebAssembly is not supported in this environment!' ) ;
}
const writeMemory = ( data , offset = 0 ) => {
memoryView . set ( data , offset ) ;
} ;
const getMemory = ( ) => memoryView ;
const getExports = ( ) => wasmInstance . exports ;
const setMemorySize = ( totalSize ) => {
wasmInstance . exports . Hash _SetMemorySize ( totalSize ) ;
const arrayOffset = wasmInstance . exports . Hash _GetBuffer ( ) ;
const memoryBuffer = wasmInstance . exports . memory . buffer ;
memoryView = new Uint8Array ( memoryBuffer , arrayOffset , totalSize ) ;
} ;
const getStateSize = ( ) => {
const view = new DataView ( wasmInstance . exports . memory . buffer ) ;
const stateSize = view . getUint32 ( wasmInstance . exports . STATE _SIZE , true ) ;
return stateSize ;
} ;
const loadWASMPromise = wasmMutex . dispatch ( ( ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
if ( ! wasmModuleCache . has ( binary . name ) ) {
const asm = decodeBase64$1 ( binary . data ) ;
const promise = WebAssembly . compile ( asm ) ;
wasmModuleCache . set ( binary . name , promise ) ;
}
const module = yield wasmModuleCache . get ( binary . name ) ;
wasmInstance = yield WebAssembly . instantiate ( module , {
// env: {
// emscripten_memcpy_big: (dest, src, num) => {
// const memoryBuffer = wasmInstance.exports.memory.buffer;
// const memView = new Uint8Array(memoryBuffer, 0);
// memView.set(memView.subarray(src, src + num), dest);
// },
// print_memory: (offset, len) => {
// const memoryBuffer = wasmInstance.exports.memory.buffer;
// const memView = new Uint8Array(memoryBuffer, 0);
// console.log('print_int32', memView.subarray(offset, offset + len));
// },
// },
} ) ;
// wasmInstance.exports._start();
} ) ) ;
const setupInterface = ( ) => _ _awaiter ( this , void 0 , void 0 , function * ( ) {
if ( ! wasmInstance ) {
yield loadWASMPromise ;
}
const arrayOffset = wasmInstance . exports . Hash _GetBuffer ( ) ;
const memoryBuffer = wasmInstance . exports . memory . buffer ;
memoryView = new Uint8Array ( memoryBuffer , arrayOffset , MAX _HEAP ) ;
} ) ;
const init = ( bits = null ) => {
initialized = true ;
wasmInstance . exports . Hash _Init ( bits ) ;
} ;
const updateUInt8Array = ( data ) => {
let read = 0 ;
while ( read < data . length ) {
const chunk = data . subarray ( read , read + MAX _HEAP ) ;
read += chunk . length ;
memoryView . set ( chunk ) ;
wasmInstance . exports . Hash _Update ( chunk . length ) ;
}
} ;
const update = ( data ) => {
if ( ! initialized ) {
throw new Error ( 'update() called before init()' ) ;
}
const Uint8Buffer = getUInt8Buffer ( data ) ;
updateUInt8Array ( Uint8Buffer ) ;
} ;
const digestChars = new Uint8Array ( hashLength * 2 ) ;
const digest = ( outputType , padding = null ) => {
if ( ! initialized ) {
throw new Error ( 'digest() called before init()' ) ;
}
initialized = false ;
wasmInstance . exports . Hash _Final ( padding ) ;
if ( outputType === 'binary' ) {
// the data is copied to allow GC of the original memory object
return memoryView . slice ( 0 , hashLength ) ;
}
return getDigestHex ( digestChars , memoryView , hashLength ) ;
} ;
const save = ( ) => {
if ( ! initialized ) {
throw new Error ( 'save() can only be called after init() and before digest()' ) ;
}
const stateOffset = wasmInstance . exports . Hash _GetState ( ) ;
const stateLength = getStateSize ( ) ;
const memoryBuffer = wasmInstance . exports . memory . buffer ;
const internalState = new Uint8Array ( memoryBuffer , stateOffset , stateLength ) ;
// prefix is 4 bytes from SHA1 hash of the WASM binary
// it is used to detect incompatible internal states between different versions of hash-wasm
const prefixedState = new Uint8Array ( WASM _FUNC _HASH _LENGTH + stateLength ) ;
writeHexToUInt8 ( prefixedState , binary . hash ) ;
prefixedState . set ( internalState , WASM _FUNC _HASH _LENGTH ) ;
return prefixedState ;
} ;
const load = ( state ) => {
if ( ! ( state instanceof Uint8Array ) ) {
throw new Error ( 'load() expects an Uint8Array generated by save()' ) ;
}
const stateOffset = wasmInstance . exports . Hash _GetState ( ) ;
const stateLength = getStateSize ( ) ;
const overallLength = WASM _FUNC _HASH _LENGTH + stateLength ;
const memoryBuffer = wasmInstance . exports . memory . buffer ;
if ( state . length !== overallLength ) {
throw new Error ( ` Bad state length (expected ${ overallLength } bytes, got ${ state . length } ) ` ) ;
}
if ( ! hexStringEqualsUInt8 ( binary . hash , state . subarray ( 0 , WASM _FUNC _HASH _LENGTH ) ) ) {
throw new Error ( 'This state was written by an incompatible hash implementation' ) ;
}
const internalState = state . subarray ( WASM _FUNC _HASH _LENGTH ) ;
new Uint8Array ( memoryBuffer , stateOffset , stateLength ) . set ( internalState ) ;
initialized = true ;
} ;
const isDataShort = ( data ) => {
if ( typeof data === 'string' ) {
// worst case is 4 bytes / char
return data . length < MAX _HEAP / 4 ;
}
return data . byteLength < MAX _HEAP ;
} ;
let canSimplify = isDataShort ;
switch ( binary . name ) {
case 'argon2' :
case 'scrypt' :
canSimplify = ( ) => true ;
break ;
case 'blake2b' :
case 'blake2s' :
// if there is a key at blake2 then cannot simplify
canSimplify = ( data , initParam ) => initParam <= 512 && isDataShort ( data ) ;
break ;
case 'blake3' :
// if there is a key at blake3 then cannot simplify
canSimplify = ( data , initParam ) => initParam === 0 && isDataShort ( data ) ;
break ;
case 'xxhash64' : // cannot simplify
case 'xxhash3' :
case 'xxhash128' :
canSimplify = ( ) => false ;
break ;
}
// shorthand for (init + update + digest) for better performance
const calculate = ( data , initParam = null , digestParam = null ) => {
if ( ! canSimplify ( data , initParam ) ) {
init ( initParam ) ;
update ( data ) ;
return digest ( 'hex' , digestParam ) ;
}
const buffer = getUInt8Buffer ( data ) ;
memoryView . set ( buffer ) ;
wasmInstance . exports . Hash _Calculate ( buffer . length , initParam , digestParam ) ;
return getDigestHex ( digestChars , memoryView , hashLength ) ;
} ;
yield setupInterface ( ) ;
return {
getMemory ,
writeMemory ,
getExports ,
setMemorySize ,
init ,
update ,
digest ,
save ,
load ,
calculate ,
hashLength ,
} ;
} ) ;
}
new Mutex ( ) ;
var name$j = "blake2b" ;
var data$j = " AGFzbQEAAAABEQRgAAF / YAJ / fwBgAX8AYAAAAwoJAAECAwECAgABBAUBcAEBAQUEAQECAgYOAn8BQbCLBQt / AEGACAsHcAgGbWVtb3J5AgAOSGFzaF9HZXRCdWZmZXIAAApIYXNoX0ZpbmFsAAMJSGFzaF9Jbml0AAULSGFzaF9VcGRhdGUABg1IYXNoX0dldFN0YXRlAAcOSGFzaF9DYWxjdWxhdGUACApTVEFURV9TSVpFAwEKjzkJBQBBgAkL5QICBH8BfgJAIAFBAUgNAAJAAkACQEGAAUEAKALgigEiAmsiAyABSA0AIAEhAwwBC0EAQQA2AuCKAQJAIAJB / wBKDQBBACEEQQAhBQNAIAQgAmpB4IkBaiAAIARqLQAAOgAAIAMgBUEBaiIFQf8BcSIESg0ACwtBAEEAKQPAiQEiBkKAAXw3A8CJAUEAQQApA8iJASAGQv9 + Vq18NwPIiQFB4IkBEAIgACADaiEAAkAgASADayIDQYEBSA0AIAIgAWohBANAQQBBACkDwIkBIgZCgAF8NwPAiQFBAEEAKQPIiQEgBkL / flatfDcDyIkBIAAQAiAAQYABaiEAIARBgH9qIgRBgAJKDQALIARBgH9qIQMLIANBAUgNAQtBACEEQQAhBQNAQQAoAuCKASAEakHgiQFqIAAgBGotAAA6AAAgAyAFQQFqIgVB / wFxIgRKDQALC0EAQQAoAuCKASADajYC4IoBCwu / LgEkfkEAIAApA2AiASAAKQNAIgIgACkDSCIDIAIgACkDGCIEIAApA1giBSAAKQMgIgYgAiAAKQMQIgcgASADIAApAwAiCCAAKQNwIgkgACkDOCIKIAggACkDeCILIAApA2giDCAGIAApA1AiDSAAKQMIIg4gCSAKIAApAzAiDyAHIA4gBCAJIA0gCCABIAEgDiACIAYgAyACIAQgB0EAKQOoiQEiEEEAKQOIiQF8fCIRfEEAKQPIiQEgEYVCn9j52cKR2oKbf4VCIIkiEUK7zqqm2NDrs7t / fCISIBCFQiiJIhB8IhMgEYVCMIkiESASfCISIBCFQgGJIhQgDiAIQQApA6CJASIQQQApA4CJASIVfHwiFnxBACkDwIkBIBaFQtGFmu / 6 z5SH0QCFQiCJIhZCiJLznf / M + YTqAHwiFyAQhUIoiSIYfCIZfHwiEHwgECAKIA9BACkDuIkBIhpBACkDmIkBfHwiG3xBACkD2IkBIBuFQvnC + JuRo7Pw2wCFQiCJIhtC8e30 + KWn / aelf3wiHCAahUIoiSIafCIdIBuFQjCJIhuFQiCJIh4gACkDKCIQIAZBACkDsIkBIh9BACkDkIkBfHwiIHxBACkD0IkBICCFQuv6htq / tfbBH4VCIIkiIEKr8NP0r + 68 tzx8IiEgH4VCKIkiH3wiIiAghUIwiSIgICF8IiF8IiMgFIVCKIkiFHwiJCAehUIwiSIeICN8IiMgFIVCAYkiFCAFIA0gISAfhUIBiSIfIBN8fCITfCATIBkgFoVCMIkiFoVCIIkiEyAbIBx8Ihl8IhsgH4VCKIkiHHwiH3x8IiF8IAwgASAZIBqFQgGJIhkgInx8Ihp8IBogEYVCIIkiESAWIBd8IhZ8IhcgGYVCKIkiGXwiGiARhUIwiSIRICGFQiCJIiEgCyAJIB0gFiAYhUIBiSIWfHwiGHwgGCAghUIgiSIYIBJ8IhIgFoVCKIkiFnwiHSAYhUIwiSIYIBJ8IhJ8IiAgFIVCKIkiFHwiIiAhhUIwiSIhICB8IiAgFIVCAYkiFCANIAkgEiAWhUIBiSISICR8fCIWfCAfIBOFQjCJIhMgFoVCIIkiFiARIBd8IhF8IhcgEoVCKIkiEnwiH3x8IiR8ICQgDyAMIBEgGYVCAYkiESAdfHwiGXwgHiAZhUIgiSIZIBMgG3wiE3wiGyARhUIoiSIRfCIdIBmFQjCJIhmFQiCJIh4gCyADIBMgHIVCAYkiEyAafHwiGnwgGCAahUIgiSIYICN8IhogE4VCKIkiE3wiHCAYhUIwiSIYIBp8Ihp8IiMgFIVCKIkiFHwiJCAehUIwiSIeICN8IiMgFIVCAYkiFCAHIAggGiAThUIBiSITICJ8fCIafCAaIB8gFoVCMIkiFoVCIIkiGiAZIBt8Ihl8IhsgE4VCKIkiE3wiH3x8IiJ8IAogBSAZIBGFQgGJIhEgHHx8Ihl8IBkgIYVCIIkiGSAWIBd8IhZ8IhcgEYVCKIkiEXwiHCAZhUIwiSIZICKFQiCJIiEgBCAdIBYgEoVCAYkiEnwgEHwiFnwgFiAYhUIgiSIWICB8IhggEoVCKIkiEnwiHSAWhUIwiSIWIBh8Ihh8IiAgFIVCKIkiFHwiIiAhhUIwiSIhICB8IiAgFIVCAYkiFCACIAUgGCAShUIBiSISICR8fCIYfCAfIBqFQjCJIhogGIVCIIkiGCAZIBd8Ihd8IhkgEoVCKIkiEnwiH3x8IiR8ICQgDCALIBcgEYVCAYkiESAdfHwiF3wgHiAXhUIgiSIXIBogG3wiGnwiGyARhUIoiSIRfCIdIBeFQjCJIheFQiCJIh4gByAaIBOFQgGJIhMgHHwgEHwiGnwgFiAahUIgiSIWICN8IhogE4VCKIkiE3wiHCAWhUIwiSIWIBp8Ihp8IiMgFIVCKIkiFHwiJCAehUIwiSIeICN8IiMgFIVCAYkiFCAPIAQgGiAThUIBiSITICJ8fCIafCAaIB8gGIVCMIkiGIVCIIkiGiAXIBt8Ihd8IhsgE4VCKIkiE3wiH3x8IiJ8IA4gCiAXIBGFQgGJIhEgHHx8Ihd8IBcgIYVCIIkiFyAYIBl8Ihh8IhkgEYVCKIkiEXwiHCAXhUIwiSIXICKFQiCJIiEgBiADIB0gGCAShUIBiSISfHwiGHwgGCAWhUIgiSIWICB8IhggEoVCKIkiEnwiHSAWhUIwiSIWIBh8Ihh8IiAgFIVCKIkiFHwiIiAhhUIwiSIhICB8IiAgFIVCAYkiFCADIAogGCAShUIBiSISICR8fCIYfCAfIBqFQjCJIhogGIVCIIkiGCAXIBl8Ihd8IhkgEoVCKIkiEnwiH3x8IiR8ICQgCSAFIBcgEYVCAYkiESAdfHwiF3wgHiAXhUIgiSIXIBogG3wiGnwiGyARhUIoiSIRfCIdIBeFQjCJIheFQiCJIh4gASAMIBogE4VCAYkiEyAcfHwiGnwgFiAahUIgiSIWICN8IhogE4VCKIkiE3wiHCAWhUIwiSIWIBp8Ihp8IiMgFIVCKIkiFHwiJCAehUIwiSIeICN8IiMgFIVCAYkiFCANIBogE4VCAYkiEyAifCAQfCIafCAaIB8gGIVCMIkiGIVCIIkiGiAXIBt8Ihd8IhsgE4VCKIkiE3wiH3wgEHwiInwgCCAGIBcgEYVCAYkiESAcfHwiF3wgFyAhhUIgiSIXIBggGXwiGHwiGSARhUIoiSIRfCIcIBeFQjCJIhcgIoVCIIkiISACIAsgHSAYIBKFQgGJIhJ8fCIYfCAYIBaFQiCJIhYgIHwiGCAShUIoiSISfCIdIBaFQjCJIhYgGHwiGHwiICAUhUIoiSIUfCIiICGFQjCJIiEgIHwiICAUhUIBiSIUIAggAyAYIBKFQgGJIhIgJHx8Ihh8IB8gGoVCMIkiGiAYhUIgiSIYIBcgGXwiF3wiGSAShUIoiSISfCIffHwiJHwgJCALIA0gFyARhUIBiSIRIB18fCIXfCAeIBeFQiCJIhcgGiAbfCIafCIbIBGFQiiJIhF8Ih0gF4VCMIkiF4VCIIkiHiAGIAcgGiAThUIBiSITIBx8fCIafCAWIBqFQiCJIhYgI3wiGiAThUIoiSITfCIcIBaFQjCJIhYgGnwiGnwiIyAUhUIoiSIUfCIkIB6FQjCJIh4gI3wiIyAUhUIBiSIUIAEgBSAaIBOFQgGJIhMgInx8Ihp8IBogHyAYhUIwiSIYhUIgiSIaIBcgG3wiF3wiGyAThUIoiSITfCIffCAPfCIifCACIBcgEYVCAYkiESAcfCAPfCIXfCAXICGFQiCJIhcgGCAZfCIYfCIZIBGFQiiJIhF8IhwgF4VCMIk
var hash$j = "68afc9cf" ;
var wasmJson$j = {
name : name$j ,
data : data$j ,
hash : hash$j
} ;
new Mutex ( ) ;
function validateBits$4 ( bits ) {
if ( ! Number . isInteger ( bits ) || bits < 8 || bits > 512 || bits % 8 !== 0 ) {
return new Error ( 'Invalid variant! Valid values: 8, 16, ..., 512' ) ;
}
return null ;
}
function getInitParam$1 ( outputBits , keyBits ) {
// eslint-disable-next-line no-bitwise
return outputBits | ( keyBits << 16 ) ;
}
/ * *
* Creates a new BLAKE2b hash instance
* @ param bits Number of output bits , which has to be a number
* divisible by 8 , between 8 and 512. Defaults to 512.
* @ param key Optional key ( string , Buffer or TypedArray ) . Maximum length is 64 bytes .
* /
function createBLAKE2b ( bits = 512 , key = null ) {
if ( validateBits$4 ( bits ) ) {
return Promise . reject ( validateBits$4 ( bits ) ) ;
}
let keyBuffer = null ;
let initParam = bits ;
if ( key !== null ) {
keyBuffer = getUInt8Buffer ( key ) ;
if ( keyBuffer . length > 64 ) {
return Promise . reject ( new Error ( 'Max key length is 64 bytes' ) ) ;
}
initParam = getInitParam$1 ( bits , keyBuffer . length ) ;
}
const outputSize = bits / 8 ;
return WASMInterface ( wasmJson$j , outputSize ) . then ( ( wasm ) => {
if ( initParam > 512 ) {
wasm . writeMemory ( keyBuffer ) ;
}
wasm . init ( initParam ) ;
const obj = {
init : initParam > 512
? ( ) => {
wasm . writeMemory ( keyBuffer ) ;
wasm . init ( initParam ) ;
return obj ;
}
: ( ) => {
wasm . init ( initParam ) ;
return obj ;
} ,
update : ( data ) => { wasm . update ( data ) ; return obj ; } ,
digest : ( outputType ) => wasm . digest ( outputType ) ,
save : ( ) => wasm . save ( ) ,
load : ( data ) => { wasm . load ( data ) ; return obj ; } ,
blockSize : 128 ,
digestSize : outputSize ,
} ;
return obj ;
} ) ;
}
var name$i = "argon2" ;
var data$i = " AGFzbQEAAAABKQVgAX8Bf2AAAX9gEH9 / f39 / f39 / f39 / f39 / f38AYAR / f39 / AGACf38AAwYFAAECAwQEBQFwAQEBBQYBAQKAgAIGCAF / AUGQqAQLB0EEBm1lbW9yeQIAEkhhc2hfU2V0TWVtb3J5U2l6ZQAADkhhc2hfR2V0QnVmZmVyAAEOSGFzaF9DYWxjdWxhdGUABArXMwVbAQF / QQAhAQJAIABBACgCgAhrIgBFDQACQCAAQRB2IABBgIB8cSAASWoiAEAAQX9HDQBB / wEhAQwBC0EAIQFBAEEAKQOACCAAQRB0rXw3A4AICyABQRh0QRh1C2oBAn8CQEEAKAKICCIADQBBAD8AQRB0IgA2AogIQYCAIEEAKAKACGsiAUUNAAJAIAFBEHYgAUGAgHxxIAFJaiIAQABBf0cNAEEADwtBAEEAKQOACCAAQRB0rXw3A4AIQQAoAogIIQALIAALnA8BA34gACAEKQMAIhAgACkDACIRfCARQgGGQv7 ///8fgyAQQv////8Pg358IhA3AwAgDCAQIAwpAwCFIhBCIIkiETcDACAIIBEgCCkDACISfCASQgGGQv7///8fgyAQQiCIfnwiEDcDACAEIBAgBCkDAIUiEEIoiSIRNwMAIAAgESAAKQMAIhJ8IBBCGIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACAMIBAgDCkDAIUiEEIwiSIRNwMAIAggESAIKQMAIhJ8IBBCEIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACAEIBAgBCkDAIVCAYk3AwAgASAFKQMAIhAgASkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDSAQIA0pAwCFIhBCIIkiETcDACAJIBEgCSkDACISfCASQgGGQv7///8fgyAQQiCIfnwiEDcDACAFIBAgBSkDAIUiEEIoiSIRNwMAIAEgESABKQMAIhJ8IBBCGIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACANIBAgDSkDAIUiEEIwiSIRNwMAIAkgESAJKQMAIhJ8IBBCEIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACAFIBAgBSkDAIVCAYk3AwAgAiAGKQMAIhAgAikDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDiAQIA4pAwCFIhBCIIkiETcDACAKIBEgCikDACISfCASQgGGQv7///8fgyAQQiCIfnwiEDcDACAGIBAgBikDAIUiEEIoiSIRNwMAIAIgESACKQMAIhJ8IBBCGIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACAOIBAgDikDAIUiEEIwiSIRNwMAIAogESAKKQMAIhJ8IBBCEIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACAGIBAgBikDAIVCAYk3AwAgAyAHKQMAIhAgAykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDyAQIA8pAwCFIhBCIIkiETcDACALIBEgCykDACISfCASQgGGQv7///8fgyAQQiCIfnwiEDcDACAHIBAgBykDAIUiEEIoiSIRNwMAIAMgESADKQMAIhJ8IBBCGIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACAPIBAgDykDAIUiEEIwiSIRNwMAIAsgESALKQMAIhJ8IBBCEIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgACAFKQMAIhAgACkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDyAQIA8pAwCFIhBCIIkiETcDACAKIBEgCikDACISfCASQgGGQv7///8fgyAQQiCIfnwiEDcDACAFIBAgBSkDAIUiEEIoiSIRNwMAIAAgESAAKQMAIhJ8IBBCGIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACAPIBAgDykDAIUiEEIwiSIRNwMAIAogESAKKQMAIhJ8IBBCEIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACAFIBAgBSkDAIVCAYk3AwAgASAGKQMAIhAgASkDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDCAQIAwpAwCFIhBCIIkiETcDACALIBEgCykDACISfCASQgGGQv7///8fgyAQQiCIfnwiEDcDACAGIBAgBikDAIUiEEIoiSIRNwMAIAEgESABKQMAIhJ8IBBCGIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACAMIBAgDCkDAIUiEEIwiSIRNwMAIAsgESALKQMAIhJ8IBBCEIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACAGIBAgBikDAIVCAYk3AwAgAiAHKQMAIhAgAikDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDSAQIA0pAwCFIhBCIIkiETcDACAIIBEgCCkDACISfCASQgGGQv7///8fgyAQQiCIfnwiEDcDACAHIBAgBykDAIUiEEIoiSIRNwMAIAIgESACKQMAIhJ8IBBCGIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACANIBAgDSkDAIUiEEIwiSIRNwMAIAggESAIKQMAIhJ8IBBCEIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACAHIBAgBykDAIVCAYk3AwAgAyAEKQMAIhAgAykDACIRfCARQgGGQv7///8fgyAQQv////8Pg358IhA3AwAgDiAQIA4pAwCFIhBCIIkiETcDACAJIBEgCSkDACISfCASQgGGQv7///8fgyAQQiCIfnwiEDcDACAEIBAgBCkDAIUiEEIoiSIRNwMAIAMgESADKQMAIhJ8IBBCGIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACAOIBAgDikDAIUiEEIwiSIRNwMAIAkgESAJKQMAIhJ8IBBCEIhC/////w+DIBJCAYZC/v///x+DfnwiEDcDACAEIBAgBCkDAIVCAYk3AwALhxoBAX9BACEEQQAgAikDACABKQMAhTcDkAhBACACKQMIIAEpAwiFNwOYCEEAIAIpAxAgASkDEIU3A6AIQQAgAikDGCABKQMYhTcDqAhBACACKQMgIAEpAyCFNwOwCEEAIAIpAyggASkDKIU3A7gIQQAgAikDMCABKQMwhTcDwAhBACACKQM4IAEpAziFNwPICEEAIAIpA0AgASkDQIU3A9AIQQAgAikDSCABKQNIhTcD2AhBACACKQNQIAEpA1CFNwPgCEEAIAIpA1ggASkDWIU3A+gIQQAgAikDYCABKQNghTcD8AhBACACKQNoIAEpA2iFNwP4CEEAIAIpA3AgASkDcIU3A4AJQQAgAikDeCABKQN4hTcDiAlBACACKQOAASABKQOAAYU3A5AJQQAgAikDiAEgASkDiAGFNwOYCUEAIAIpA5ABIAEpA5ABhTcDoAlBACACKQOYASABKQOYAYU3A6gJQQAgAikDoAEgASkDoAGFNwOwCUEAIAIpA6gBIAEpA6gBhTcDuAlBACACKQOwASABKQOwAYU3A8AJQQAgAikDuAEgASkDuAGFNwPICUEAIAIpA8ABIAEpA8ABhTcD0AlBACACKQPIASABKQPIAYU3A9gJQQAgAikD0AEgASkD0AGFNwPgCUEAIAIpA9gBIAEpA9gBhTcD6AlBACACKQPgASABKQPgAYU3A/AJQQAgAikD6AEgASkD6AGFNwP4CUEAIAIpA/ABIAEpA/ABhTcDgApBACACKQP4ASABKQP4AYU3A4gKQQAgAikDgAIgASkDgAKFNwOQCkEAIAIpA4gCIAEpA4gChTcDmApBACACKQOQAiABKQOQAoU3A6AKQQAgAikDmAIgASkDmAKFNwOoCkEAIAIpA6ACIAEpA6AChTcDsApBACACKQOoAiABKQOoAoU3A7gKQQAgAikDsAIgASkDsAKFNwPACkEAIAIpA7gCIAEpA7gChTcDyApBACACKQPAAiABKQPAAoU3A9A
var hash$i = "59aa4fb4" ;
var wasmJson$i = {
name : name$i ,
data : data$i ,
hash : hash$i
} ;
function encodeResult ( salt , options , res ) {
const parameters = [
` m= ${ options . memorySize } ` ,
` t= ${ options . iterations } ` ,
` p= ${ options . parallelism } ` ,
] . join ( ',' ) ;
return ` $ argon2 ${ options . hashType } $ v=19 $ ${ parameters } $ ${ encodeBase64$1 ( salt , false ) } $ ${ encodeBase64$1 ( res , false ) } ` ;
}
const uint32View = new DataView ( new ArrayBuffer ( 4 ) ) ;
function int32LE ( x ) {
uint32View . setInt32 ( 0 , x , true ) ;
return new Uint8Array ( uint32View . buffer ) ;
}
function hashFunc ( blake512 , buf , len ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
if ( len <= 64 ) {
const blake = yield createBLAKE2b ( len * 8 ) ;
blake . update ( int32LE ( len ) ) ;
blake . update ( buf ) ;
return blake . digest ( 'binary' ) ;
}
const r = Math . ceil ( len / 32 ) - 2 ;
const ret = new Uint8Array ( len ) ;
blake512 . init ( ) ;
blake512 . update ( int32LE ( len ) ) ;
blake512 . update ( buf ) ;
let vp = blake512 . digest ( 'binary' ) ;
ret . set ( vp . subarray ( 0 , 32 ) , 0 ) ;
for ( let i = 1 ; i < r ; i ++ ) {
blake512 . init ( ) ;
blake512 . update ( vp ) ;
vp = blake512 . digest ( 'binary' ) ;
ret . set ( vp . subarray ( 0 , 32 ) , i * 32 ) ;
}
const partialBytesNeeded = len - 32 * r ;
let blakeSmall ;
if ( partialBytesNeeded === 64 ) {
blakeSmall = blake512 ;
blakeSmall . init ( ) ;
}
else {
blakeSmall = yield createBLAKE2b ( partialBytesNeeded * 8 ) ;
}
blakeSmall . update ( vp ) ;
vp = blakeSmall . digest ( 'binary' ) ;
ret . set ( vp . subarray ( 0 , partialBytesNeeded ) , r * 32 ) ;
return ret ;
} ) ;
}
function getHashType ( type ) {
switch ( type ) {
case 'd' :
return 0 ;
case 'i' :
return 1 ;
default :
return 2 ;
}
}
function argon2Internal ( options ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
const { parallelism , iterations , hashLength } = options ;
const password = getUInt8Buffer ( options . password ) ;
const salt = getUInt8Buffer ( options . salt ) ;
const version = 0x13 ;
const hashType = getHashType ( options . hashType ) ;
const { memorySize } = options ; // in KB
const [ argon2Interface , blake512 ] = yield Promise . all ( [
WASMInterface ( wasmJson$i , 1024 ) ,
createBLAKE2b ( 512 ) ,
] ) ;
// last block is for storing the init vector
argon2Interface . setMemorySize ( memorySize * 1024 + 1024 ) ;
const initVector = new Uint8Array ( 24 ) ;
const initVectorView = new DataView ( initVector . buffer ) ;
initVectorView . setInt32 ( 0 , parallelism , true ) ;
initVectorView . setInt32 ( 4 , hashLength , true ) ;
initVectorView . setInt32 ( 8 , memorySize , true ) ;
initVectorView . setInt32 ( 12 , iterations , true ) ;
initVectorView . setInt32 ( 16 , version , true ) ;
initVectorView . setInt32 ( 20 , hashType , true ) ;
argon2Interface . writeMemory ( initVector , memorySize * 1024 ) ;
blake512 . init ( ) ;
blake512 . update ( initVector ) ;
blake512 . update ( int32LE ( password . length ) ) ;
blake512 . update ( password ) ;
blake512 . update ( int32LE ( salt . length ) ) ;
blake512 . update ( salt ) ;
blake512 . update ( int32LE ( 0 ) ) ; // key length + key
blake512 . update ( int32LE ( 0 ) ) ; // associatedData length + associatedData
const segments = Math . floor ( memorySize / ( parallelism * 4 ) ) ; // length of each lane
const lanes = segments * 4 ;
const param = new Uint8Array ( 72 ) ;
const H0 = blake512 . digest ( 'binary' ) ;
param . set ( H0 ) ;
for ( let lane = 0 ; lane < parallelism ; lane ++ ) {
param . set ( int32LE ( 0 ) , 64 ) ;
param . set ( int32LE ( lane ) , 68 ) ;
let position = lane * lanes ;
let chunk = yield hashFunc ( blake512 , param , 1024 ) ;
argon2Interface . writeMemory ( chunk , position * 1024 ) ;
position += 1 ;
param . set ( int32LE ( 1 ) , 64 ) ;
chunk = yield hashFunc ( blake512 , param , 1024 ) ;
argon2Interface . writeMemory ( chunk , position * 1024 ) ;
}
const C = new Uint8Array ( 1024 ) ;
writeHexToUInt8 ( C , argon2Interface . calculate ( new Uint8Array ( [ ] ) , memorySize ) ) ;
const res = yield hashFunc ( blake512 , C , hashLength ) ;
if ( options . outputType === 'hex' ) {
const digestChars = new Uint8Array ( hashLength * 2 ) ;
return getDigestHex ( digestChars , res , hashLength ) ;
}
if ( options . outputType === 'encoded' ) {
return encodeResult ( salt , options , res ) ;
}
// return binary format
return res ;
} ) ;
}
const validateOptions$3 = ( options ) => {
if ( ! options || typeof options !== 'object' ) {
throw new Error ( 'Invalid options parameter. It requires an object.' ) ;
}
if ( ! options . password ) {
throw new Error ( 'Password must be specified' ) ;
}
options . password = getUInt8Buffer ( options . password ) ;
if ( options . password . length < 1 ) {
throw new Error ( 'Password must be specified' ) ;
}
if ( ! options . salt ) {
throw new Error ( 'Salt must be specified' ) ;
}
options . salt = getUInt8Buffer ( options . salt ) ;
if ( options . salt . length < 8 ) {
throw new Error ( 'Salt should be at least 8 bytes long' ) ;
}
if ( ! Number . isInteger ( options . iterations ) || options . iterations < 1 ) {
throw new Error ( 'Iterations should be a positive number' ) ;
}
if ( ! Number . isInteger ( options . parallelism ) || options . parallelism < 1 ) {
throw new Error ( 'Parallelism should be a positive number' ) ;
}
if ( ! Number . isInteger ( options . hashLength ) || options . hashLength < 4 ) {
throw new Error ( 'Hash length should be at least 4 bytes.' ) ;
}
if ( ! Number . isInteger ( options . memorySize ) ) {
throw new Error ( 'Memory size should be specified.' ) ;
}
if ( options . memorySize < 8 * options . parallelism ) {
throw new Error ( 'Memory size should be at least 8 * parallelism.' ) ;
}
if ( options . outputType === undefined ) {
options . outputType = 'hex' ;
}
if ( ! [ 'hex' , 'binary' , 'encoded' ] . includes ( options . outputType ) ) {
throw new Error ( ` Insupported output type ${ options . outputType } . Valid values: ['hex', 'binary', 'encoded'] ` ) ;
}
} ;
const getHashParameters = ( password , encoded ) => {
const regex = /^\$argon2(id|i|d)\$v=([0-9]+)\$((?:[mtp]=[0-9]+,){2}[mtp]=[0-9]+)\$([A-Za-z0-9+/]+)\$([A-Za-z0-9+/]+)$/ ;
const match = encoded . match ( regex ) ;
if ( ! match ) {
throw new Error ( 'Invalid hash' ) ;
}
const [ , hashType , version , parameters , salt , hash ] = match ;
if ( version !== '19' ) {
throw new Error ( ` Unsupported version: ${ version } ` ) ;
}
const parsedParameters = { } ;
const paramMap = { m : 'memorySize' , p : 'parallelism' , t : 'iterations' } ;
parameters . split ( ',' ) . forEach ( ( x ) => {
const [ n , v ] = x . split ( '=' ) ;
parsedParameters [ paramMap [ n ] ] = parseInt ( v , 10 ) ;
} ) ;
return Object . assign ( Object . assign ( { } , parsedParameters ) , { password , hashType : hashType , salt : decodeBase64$1 ( salt ) , hashLength : getDecodeBase64Length ( hash ) , outputType : 'encoded' } ) ;
} ;
const validateVerifyOptions$1 = ( options ) => {
if ( ! options || typeof options !== 'object' ) {
throw new Error ( 'Invalid options parameter. It requires an object.' ) ;
}
if ( options . hash === undefined || typeof options . hash !== 'string' ) {
throw new Error ( 'Hash should be specified' ) ;
}
} ;
/ * *
* Verifies password using the argon2 password - hashing function
* @ returns True if the encoded hash matches the password
* /
function argon2Verify ( options ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
validateVerifyOptions$1 ( options ) ;
const params = getHashParameters ( options . password , options . hash ) ;
validateOptions$3 ( params ) ;
const hashStart = options . hash . lastIndexOf ( '$' ) + 1 ;
const result = yield argon2Internal ( params ) ;
return result . substring ( hashStart ) === options . hash . substring ( hashStart ) ;
} ) ;
}
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
new Mutex ( ) ;
var name$2 = "bcrypt" ;
var data$2 = " AGFzbQEAAAABFwRgAAF / YAR / f39 / AGADf39 / AGABfwF / AwUEAAECAwQFAXABAQEFBAEBAgIGCAF / AUGQqwULBzQEBm1lbW9yeQIADkhhc2hfR2V0QnVmZmVyAAAGYmNyeXB0AAINYmNyeXB0X3ZlcmlmeQADCuRbBAUAQYArC5FVAxJ / BX4HfyMAQfAAayEEIAJBADoAAiACQargADsAAAJAIAEtAABBKkcNACABLQABQTBHDQAgAkExOgABCwJAIAEsAAUgASwABEEKbGpB8HtqIgVBBEkNAEEBIAV0IQYgAUEHaiEFIARBGGohByAEQQhqIQgDQCAFLQAAQWBqIglB3wBLDQEgCUGACGotAAAiCkE / Sw0BIAVBAWotAABBYGoiCUHfAEsNASAJQYAIai0AACIJQT9LDQEgCCAJQQR2IApBAnRyOgAAAkAgCEEBaiIIIAdPDQAgBUECai0AAEFgaiIKQd8ASw0CIApBgAhqLQAAIgpBP0sNAiAIIApBAnYgCUEEdHI6AAAgCEEBaiIIIAdPDQAgBUEDai0AAEFgaiIJQd8ASw0CIAlBgAhqLQAAIglBP0sNAiAIIAkgCkEGdHI6AAAgBUEEaiEFIAhBAWoiCCAHSQ0BCwsgBCAEKAIIIgVBGHQgBUEIdEGAgPwHcXIgBUEIdkGA / gNxIAVBGHZyciILNgIIIAQgBCgCDCIFQRh0IAVBCHRBgID8B3FyIAVBCHZBgP4DcSAFQRh2cnIiDDYCDCAEIAQoAhAiBUEYdCAFQQh0QYCA / AdxciAFQQh2QYD + A3EgBUEYdnJyNgIQIAQgBCgCFCIFQRh0IAVBCHRBgID8B3FyIAVBCHZBgP4DcSAFQRh2cnI2AhQgBEHoAGogAS0AAkH / B2otAAAiDUEBcUECdGohDkEAIQhBACEJQQAhCiAAIQUDQCAEQgA3AmggBS0AACEHIARBADYCbCAEIAc2AmggBCAFLAAAIg82AmwgBS0AACEQIAQgB0EIdCIHNgJoIAQgByAFQQFqIAAgEBsiBS0AAHIiBzYCaCAEIA9BCHQiDzYCbCAEIA8gBSwAACIQciIPNgJsIAUtAAAhESAEIAdBCHQiBzYCaCAEIAcgBUEBaiAAIBEbIgUtAAByIgc2AmggBCAPQQh0Ig82AmwgBCAPIAUsAAAiEXIiDzYCbCAFLQAAIRIgBCAHQQh0Igc2AmggBCAHIAVBAWogACASGyIFLQAAciIHNgJoIAQgD0EIdCIPNgJsIAQgDyAFLAAAIhJyIg82AmwgBS0AACETIARBIGogCGogDigCACIUNgIAIAhB6ClqIhUgFCAVKAIAczYCACAPIAdzIAlyIQkgBUEBaiAAIBMbIQUgEEGAAXEgCnIgEUGAAXFyIBJBgAFxciEKIAhBBGoiCEHIAEcNAAtBAEEAKALoKSANQQ90IApBCXRxQYCABCAJQf //A3EgCUEQdnJrcUGAgARxcyIFNgLoKUIAIRZBAEIANwOAqwFB6CkhB0EAIQgCQANAQQAoAqQqQQAoApwqQQAoApQqQQAoAowqQQAoAoQqQQAoAvwpQQAoAvQpQQAoAuwpIARBCGogCEECcUECdGopAwAgFoUiFkIgiKdzIAUgFqdzIgVBFnZB/AdxQegJaigCACAFQQ52QfwHcUHoEWooAgBqIAVBBnZB/AdxQegZaigCAHMgBUH/AXFBAnRB6CFqKAIAanMiAHNBACgC8CkgBXMgAEEWdkH8B3FB6AlqKAIAIABBDnZB/AdxQegRaigCAGogAEEGdkH8B3FB6BlqKAIAcyAAQf8BcUECdEHoIWooAgBqcyIFQRZ2QfwHcUHoCWooAgAgBUEOdkH8B3FB6BFqKAIAaiAFQQZ2QfwHcUHoGWooAgBzIAVB/wFxQQJ0QeghaigCAGpzIgBzQQAoAvgpIAVzIABBFnZB/AdxQegJaigCACAAQQ52QfwHcUHoEWooAgBqIABBBnZB/AdxQegZaigCAHMgAEH/AXFBAnRB6CFqKAIAanMiBUEWdkH8B3FB6AlqKAIAIAVBDnZB/AdxQegRaigCAGogBUEGdkH8B3FB6BlqKAIAcyAFQf8BcUECdEHoIWooAgBqcyIAc0EAKAKAKiAFcyAAQRZ2QfwHcUHoCWooAgAgAEEOdkH8B3FB6BFqKAIAaiAAQQZ2QfwHcUHoGWooAgBzIABB/wFxQQJ0QeghaigCAGpzIgVBFnZB/AdxQegJaigCACAFQQ52QfwHcUHoEWooAgBqIAVBBnZB/AdxQegZaigCAHMgBUH/AXFBAnRB6CFqKAIAanMiAHNBACgCiCogBXMgAEEWdkH8B3FB6AlqKAIAIABBDnZB/AdxQegRaigCAGogAEEGdkH8B3FB6BlqKAIAcyAAQf8BcUECdEHoIWooAgBqcyIFQRZ2QfwHcUHoCWooAgAgBUEOdkH8B3FB6BFqKAIAaiAFQQZ2QfwHcUHoGWooAgBzIAVB/wFxQQJ0QeghaigCAGpzIgBzQQAoApAqIAVzIABBFnZB/AdxQegJaigCACAAQQ52QfwHcUHoEWooAgBqIABBBnZB/AdxQegZaigCAHMgAEH/AXFBAnRB6CFqKAIAanMiBUEWdkH8B3FB6AlqKAIAIAVBDnZB/AdxQegRaigCAGogBUEGdkH8B3FB6BlqKAIAcyAFQf8BcUECdEHoIWooAgBqcyIAc0EAKAKYKiAFcyAAQRZ2QfwHcUHoCWooAgAgAEEOdkH8B3FB6BFqKAIAaiAAQQZ2QfwHcUHoGWooAgBzIABB/wFxQQJ0QeghaigCAGpzIgVBFnZB/AdxQegJaigCACAFQQ52QfwHcUHoEWooAgBqIAVBBnZB/AdxQegZaigCAHMgBUH/AXFBAnRB6CFqKAIAanMiAHNBACgCoCogBXMgAEEWdkH8B3FB6AlqKAIAIABBDnZB/AdxQegRaigCAGogAEEGdkH8B3FB6BlqKAIAcyAAQf8BcUECdEHoIWooAgBqcyIFQRZ2QfwHcUHoCWooAgAgBUEOdkH8B3FB6BFqKAIAaiAFQQZ2QfwHcUHoGWooAgBzIAVB/wFxQQJ0QeghaigCAGpzIgBB/wFxQQJ0QeghaigCACEJIABBBnZB/AdxQegZaigCACEKIABBFnZB/AdxQegJaigCACEPIABBDnZB/AdxQegRaigCACEQQQAoAqgqIRFBAEEAKAKsKiAAczYCgKsBQQAgESAFcyAJIAogDyAQanNqcyIANgKEqwEgB0EAKQOAqwEiFjcCACAIQQ9LDQEgB0EIaiEHIAhBAmohCEEAKALoKSEFDAALCyAWpyEIQegJIQUDQEEAKAKkKkEAKAKcKkEAKAKUKkEAKAKMKkEAKAKEKkEAKAL8KUEAKAL0KSAEKAIUIABzQQAoAuwpcyAEKAIQIAhzQQAoAugpcyIAQRZ2QfwHcUHoCWooAgAgAEEOdkH8B3FB6BFqKAIAaiAAQQZ2QfwHcUHoGWooAgBzIABB/wFxQQJ0QeghaigCAGpzIghzQQAoAvApIABzIAhBFnZB/AdxQegJaigCACAIQQ52QfwHcUHoEWooAgBqIAhBBnZB/AdxQegZaigCAHMgCEH/AXFBAnRB6CFqKAIAanMiAEEWdkH8B3FB6AlqKAIAIABBDnZB/AdxQegRaigCAGogAEEGdkH8B3FB6BlqKAIAcyAAQf8BcUECdEHoIWooAgBqcyIIc0EAKAL4KSAAcyAIQRZ2QfwHcUHoCWooAgAgCEEOdkH8B3FB6BFqKAIAaiAIQQZ2QfwHcUHoGWooAgBzIAhB/wFxQQJ0QeghaigCAGpzIgBBFnZB/AdxQegJaigCACAAQQ52QfwHcUHoEWooAgBqIABBBnZB/AdxQegZaigCAHMgAEH/AXFBAnRB6CFqKAIAanMiCHNBACgCgCogAHMgCEEWdkH8B3FB6AlqKAIAIAhBDnZB/AdxQegRaigCAGogCEEGdkH8B3FB6BlqKAIAcyAIQf8BcUECdEHoIWooAgBqcyIAQRZ2QfwHcUHoCWooAgAgAEEOdkH8B3FB6BFqKAIAaiA
var hash$2 = "9f4c7b9e" ;
var wasmJson$2 = {
name : name$2 ,
data : data$2 ,
hash : hash$2
} ;
const validateHashCharacters = ( hash ) => {
if ( ! /^\$2[axyb]\$[0-3][0-9]\$[./A-Za-z0-9]{53}$/ . test ( hash ) ) {
return false ;
}
if ( hash [ 4 ] === '0' && parseInt ( hash [ 5 ] , 10 ) < 4 ) {
return false ;
}
if ( hash [ 4 ] === '3' && parseInt ( hash [ 5 ] , 10 ) > 1 ) {
return false ;
}
return true ;
} ;
const validateVerifyOptions = ( options ) => {
if ( ! options || typeof options !== 'object' ) {
throw new Error ( 'Invalid options parameter. It requires an object.' ) ;
}
if ( options . hash === undefined || typeof options . hash !== 'string' ) {
throw new Error ( 'Hash should be specified' ) ;
}
if ( options . hash . length !== 60 ) {
throw new Error ( 'Hash should be 60 bytes long' ) ;
}
if ( ! validateHashCharacters ( options . hash ) ) {
throw new Error ( 'Invalid hash' ) ;
}
options . password = getUInt8Buffer ( options . password ) ;
if ( options . password . length < 1 ) {
throw new Error ( 'Password should be at least 1 byte long' ) ;
}
if ( options . password . length > 72 ) {
throw new Error ( 'Password should be at most 72 bytes long' ) ;
}
} ;
/ * *
* Verifies password using bcrypt password - hashing function
* @ returns True if the encoded hash matches the password
* /
function bcryptVerify ( options ) {
return _ _awaiter ( this , void 0 , void 0 , function * ( ) {
validateVerifyOptions ( options ) ;
const { hash , password } = options ;
const bcryptInterface = yield WASMInterface ( wasmJson$2 , 0 ) ;
bcryptInterface . writeMemory ( getUInt8Buffer ( hash ) , 0 ) ;
const passwordBuffer = getUInt8Buffer ( password ) ;
bcryptInterface . writeMemory ( passwordBuffer , 60 ) ;
return ! ! bcryptInterface . getExports ( ) . bcrypt _verify ( passwordBuffer . length ) ;
} ) ;
}
new Mutex ( ) ;
new Mutex ( ) ;
// Generated using scripts/write-decode-map.ts
var htmlDecodeTree = new Uint16Array (
// prettier-ignore
" \u1d41 < \ xd5\u0131\u028a\u049d\u057b\u05d0\u0675\u06de\u07a2\u07d6\u080f\u0a4a\u0a91\u0da1\u0e6d\u0f09\u0f26\u10ca\u1228\u12e1\u1415\u149d\u14c3\u14df\u1525 \ 0 \ 0 \ 0 \ 0 \ 0 \ 0 \u156b\u16cd\u198d\u1c12\u1ddd\u1f7e\u2060\u21b0\u228d\u23c0\u23fb\u2442\u2824\u2912\u2d08\u2e48\u2fce\u3016\u32ba\u3639\u37ac\u38fe\u3a28\u3a71\u3ae0\u3b2e\u0800EMabcfglmnoprstu \ \ bfms \ x7f \ x84 \ x8b \ x90 \ x95 \ x98 \ xa6 \ xb3 \ xb9 \ xc8 \ xcflig\u803b \ xc6\u40c6P\u803b & \u4026cute\u803b \ xc1\u40c1reve ; \u4102\u0100iyx } rc\u803b \ xc2\u40c2 ; \u4410r ; \uc000\ud835\udd04rave\u803b \ xc0\u40c0pha ; \u4391acr ; \u4100d ; \u6a53\u0100gp \ x9d \ xa1on ; \u4104f ; \uc000\ud835\udd38plyFunction ; \u6061ing\u803b \ xc5\u40c5\u0100cs \ xbe \ xc3r ; \uc000\ud835\udc9cign ; \u6254ilde\u803b \ xc3\u40c3ml\u803b \ xc4\u40c4\u0400aceforsu \ xe5 \ xfb \ xfe\u0117\u011c\u0122\u0127\u012a\u0100cr \ xea \ xf2kslash ; \u6216\u0176 \ xf6 \ xf8 ; \u6ae7ed ; \u6306y ; \u4411\u0180crt\u0105\u010b\u0114ause ; \u6235noullis ; \u612ca ; \u4392r ; \uc000\ud835\udd05pf ; \uc000\ud835\udd39eve ; \u42d8c \ xf2\u0113mpeq ; \u624e\u0700HOacdefhilorsu\u014d\u0151\u0156\u0180\u019e\u01a2\u01b5\u01b7\u01ba\u01dc\u0215\u0273\u0278\u027ecy ; \u4427PY\u803b \ xa9\u40a9\u0180cpy\u015d\u0162\u017aute ; \u4106\u0100 ; i\u0167\u0168\u62d2talDifferentialD ; \u6145leys ; \u612d\u0200aeio\u0189\u018e\u0194\u0198ron ; \u410cdil\u803b \ xc7\u40c7rc ; \u4108nint ; \u6230ot ; \u410a\u0100dn\u01a7\u01adilla ; \u40b8terDot ; \u40b7 \ xf2\u017fi ; \u43a7rcle\u0200DMPT\u01c7\u01cb\u01d1\u01d6ot ; \u6299inus ; \u6296lus ; \u6295imes ; \u6297o\u0100cs\u01e2\u01f8kwiseContourIntegral ; \u6232eCurly\u0100DQ\u0203\u020foubleQuote ; \u601duote ; \u6019\u0200lnpu\u021e\u0228\u0247\u0255on\u0100 ; e\u0225\u0226\u6237 ; \u6a74\u0180git\u022f\u0236\u023aruent ; \u6261nt ; \u622fourIntegral ; \u622e\u0100fr\u024c\u024e ; \u6102oduct ; \u6210nterClockwiseContourIntegral ; \u6233oss ; \u6a2fcr ; \uc000\ud835\udc9ep\u0100 ; C\u0284\u0285\u62d3ap ; \u624d\u0580DJSZacefios\u02a0\u02ac\u02b0\u02b4\u02b8\u02cb\u02d7\u02e1\u02e6\u0333\u048d\u0100 ; o\u0179\u02a5trahd ; \u6911cy ; \u4402cy ; \u4405cy ; \u440f\u0180grs\u02bf\u02c4\u02c7ger ; \u6021r ; \u61a1hv ; \u6ae4\u0100ay\u02d0\u02d5ron ; \u410e ; \u4414l\u0100 ; t\u02dd\u02de\u6207a ; \u4394r ; \uc000\ud835\udd07\u0100af\u02eb\u0327\u0100cm\u02f0\u0322ritical\u0200ADGT\u0300\u0306\u0316\u031ccute ; \u40b4o\u0174\u030b\u030d ; \u42d9bleAcute ; \u42ddrave ; \u4060ilde ; \u42dcond ; \u62c4ferentialD ; \u6146\u0470\u033d \ 0 \ 0 \ 0 \u0342\u0354 \ 0 \u0405f ; \uc000\ud835\udd3b\u0180 ; DE\u0348\u0349\u034d\u40a8ot ; \u60dcqual ; \u6250ble\u0300CDLRUV\u0363\u0372\u0382\u03cf\u03e2\u03f8ontourIntegra \ xec\u0239o\u0274\u0379 \ 0 \ 0 \u037b \ xbb\u0349nArrow ; \u61d3\u0100eo\u0387\u03a4ft\u0180ART\u0390\u0396\u03a1rrow ; \u61d0ightArrow ; \u61d4e \ xe5\u02cang\u0100LR\u03ab\u03c4eft\u0100AR\u03b3\u03b9rrow ; \u67f8ightArrow ; \u67faightArrow ; \u67f9ight\u0100AT\u03d8\u03derrow ; \u61d2ee ; \u62a8p\u0241\u03e9 \ 0 \ 0 \u03efrrow ; \u61d1ownArrow ; \u61d5erticalBar ; \u6225n\u0300ABLRTa\u0412\u042a\u0430\u045e\u047f\u037crrow\u0180 ; BU\u041d\u041e\u0422\u6193ar ; \u6913pArrow ; \u61f5reve ; \u4311eft\u02d2\u043a \ 0 \u0446 \ 0 \u0450ightVector ; \u6950eeVector ; \u695eector\u0100 ; B\u0459\u045a\u61bdar ; \u6956ight\u01d4\u0467 \ 0 \u0471eeVector ; \u695fector\u0100 ; B\u047a\u047b\u61c1ar ; \u6957ee\u0100 ; A\u0486\u0487\u62a4rrow ; \u61a7\u0100ct\u0492\u0497r ; \uc000\ud835\udc9frok ; \u4110\u0800NTacdfglmopqstux\u04bd\u04c0\u04c4\u04cb\u04de\u04e2\u04e7\u04ee\u04f5\u0521\u052f\u0536\u0552\u055d\u0560\u0565G ; \u414aH\u803b \ xd0\u40d0cute\u803b \ xc9\u40c9\u0180aiy\u04d2\u04d7\u04dcron ; \u411arc\u803b \ xca\u40ca ; \u442dot ; \u4116r ; \uc000\ud835\udd08rave\u803b \ xc8\u40c8ement ; \u6208\u0100ap\u04fa\u04fecr ; \u4112ty\u0253\u0506 \ 0 \ 0 \u0512mallSquare ; \u65fberySmallSquare ; \u65ab\u0100gp\u0526\u052aon ; \u4118f ; \uc000\ud835\udd3csilon ; \u4395u\u0100ai\u053c\u0549l\u0100 ; T\u0542\u0543\u6a75ilde ; \u6242librium ; \u61cc\u0100ci\u0557\u055ar ; \u6130m ; \u6a73a ; \u4397ml\u803b \ xcb\u40cb\u0100ip\u056a\u056fsts ; \u6203onentialE ; \u6147\u0280cfios\u0585\u0588\u058d\u05b2\u05ccy ; \u4424r ; \uc000\ud835\udd09lled\u0253\u0597 \ 0 \ 0 \u05a3mallSquare ; \u65fcerySmallSquare ; \u65aa\u0370\u05ba \ 0 \u05bf \ 0 \ 0 \u05c4f ; \uc000\ud835\udd3dAll ; \u6200riertrf ; \u6131c \ xf2\u05cb\u0600JTabcdfgorst\u05e8\u05ec\u05ef\u05fa\u0600\u0612 \ u
. split ( "" )
. map ( ( c ) => c . charCodeAt ( 0 ) ) ) ;
// Generated using scripts/write-decode-map.ts
var xmlDecodeTree = new Uint16Array (
// prettier-ignore
"\u0200aglq\t\x15\x18\x1b\u026d\x0f\0\0\x12p;\u4026os;\u4027t;\u403et;\u403cuot;\u4022"
. split ( "" )
. map ( ( c ) => c . charCodeAt ( 0 ) ) ) ;
// Adapted from https://github.com/mathiasbynens/he/blob/36afe179392226cf1b6ccdb16ebbb7a5a844d93a/src/he.js#L106-L134
var _a ;
const decodeMap = new Map ( [
[ 0 , 65533 ] ,
[ 128 , 8364 ] ,
[ 130 , 8218 ] ,
[ 131 , 402 ] ,
[ 132 , 8222 ] ,
[ 133 , 8230 ] ,
[ 134 , 8224 ] ,
[ 135 , 8225 ] ,
[ 136 , 710 ] ,
[ 137 , 8240 ] ,
[ 138 , 352 ] ,
[ 139 , 8249 ] ,
[ 140 , 338 ] ,
[ 142 , 381 ] ,
[ 145 , 8216 ] ,
[ 146 , 8217 ] ,
[ 147 , 8220 ] ,
[ 148 , 8221 ] ,
[ 149 , 8226 ] ,
[ 150 , 8211 ] ,
[ 151 , 8212 ] ,
[ 152 , 732 ] ,
[ 153 , 8482 ] ,
[ 154 , 353 ] ,
[ 155 , 8250 ] ,
[ 156 , 339 ] ,
[ 158 , 382 ] ,
[ 159 , 376 ] ,
] ) ;
const fromCodePoint =
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition, node/no-unsupported-features/es-builtins
( _a = String . fromCodePoint ) !== null && _a !== void 0 ? _a : function ( codePoint ) {
let output = "" ;
if ( codePoint > 0xffff ) {
codePoint -= 0x10000 ;
output += String . fromCharCode ( ( ( codePoint >>> 10 ) & 0x3ff ) | 0xd800 ) ;
codePoint = 0xdc00 | ( codePoint & 0x3ff ) ;
}
output += String . fromCharCode ( codePoint ) ;
return output ;
} ;
function replaceCodePoint ( codePoint ) {
var _a ;
if ( ( codePoint >= 0xd800 && codePoint <= 0xdfff ) || codePoint > 0x10ffff ) {
return 0xfffd ;
}
return ( _a = decodeMap . get ( codePoint ) ) !== null && _a !== void 0 ? _a : codePoint ;
}
function decodeCodePoint ( codePoint ) {
return fromCodePoint ( replaceCodePoint ( codePoint ) ) ;
}
var CharCodes ;
( function ( CharCodes ) {
CharCodes [ CharCodes [ "NUM" ] = 35 ] = "NUM" ;
CharCodes [ CharCodes [ "SEMI" ] = 59 ] = "SEMI" ;
CharCodes [ CharCodes [ "ZERO" ] = 48 ] = "ZERO" ;
CharCodes [ CharCodes [ "NINE" ] = 57 ] = "NINE" ;
CharCodes [ CharCodes [ "LOWER_A" ] = 97 ] = "LOWER_A" ;
CharCodes [ CharCodes [ "LOWER_F" ] = 102 ] = "LOWER_F" ;
CharCodes [ CharCodes [ "LOWER_X" ] = 120 ] = "LOWER_X" ;
/** Bit that needs to be set to convert an upper case ASCII character to lower case */
CharCodes [ CharCodes [ "To_LOWER_BIT" ] = 32 ] = "To_LOWER_BIT" ;
} ) ( CharCodes || ( CharCodes = { } ) ) ;
var BinTrieFlags ;
( function ( BinTrieFlags ) {
BinTrieFlags [ BinTrieFlags [ "VALUE_LENGTH" ] = 49152 ] = "VALUE_LENGTH" ;
BinTrieFlags [ BinTrieFlags [ "BRANCH_LENGTH" ] = 16256 ] = "BRANCH_LENGTH" ;
BinTrieFlags [ BinTrieFlags [ "JUMP_TABLE" ] = 127 ] = "JUMP_TABLE" ;
} ) ( BinTrieFlags || ( BinTrieFlags = { } ) ) ;
function getDecoder ( decodeTree ) {
return function decodeHTMLBinary ( str , strict ) {
let ret = "" ;
let lastIdx = 0 ;
let strIdx = 0 ;
while ( ( strIdx = str . indexOf ( "&" , strIdx ) ) >= 0 ) {
ret += str . slice ( lastIdx , strIdx ) ;
lastIdx = strIdx ;
// Skip the "&"
strIdx += 1 ;
// If we have a numeric entity, handle this separately.
if ( str . charCodeAt ( strIdx ) === CharCodes . NUM ) {
// Skip the leading "&#". For hex entities, also skip the leading "x".
let start = strIdx + 1 ;
let base = 10 ;
let cp = str . charCodeAt ( start ) ;
if ( ( cp | CharCodes . To _LOWER _BIT ) === CharCodes . LOWER _X ) {
base = 16 ;
strIdx += 1 ;
start += 1 ;
}
do
cp = str . charCodeAt ( ++ strIdx ) ;
while ( ( cp >= CharCodes . ZERO && cp <= CharCodes . NINE ) ||
( base === 16 &&
( cp | CharCodes . To _LOWER _BIT ) >= CharCodes . LOWER _A &&
( cp | CharCodes . To _LOWER _BIT ) <= CharCodes . LOWER _F ) ) ;
if ( start !== strIdx ) {
const entity = str . substring ( start , strIdx ) ;
const parsed = parseInt ( entity , base ) ;
if ( str . charCodeAt ( strIdx ) === CharCodes . SEMI ) {
strIdx += 1 ;
}
else if ( strict ) {
continue ;
}
ret += decodeCodePoint ( parsed ) ;
lastIdx = strIdx ;
}
continue ;
}
let resultIdx = 0 ;
let excess = 1 ;
let treeIdx = 0 ;
let current = decodeTree [ treeIdx ] ;
for ( ; strIdx < str . length ; strIdx ++ , excess ++ ) {
treeIdx = determineBranch ( decodeTree , current , treeIdx + 1 , str . charCodeAt ( strIdx ) ) ;
if ( treeIdx < 0 )
break ;
current = decodeTree [ treeIdx ] ;
const masked = current & BinTrieFlags . VALUE _LENGTH ;
// If the branch is a value, store it and continue
if ( masked ) {
// If we have a legacy entity while parsing strictly, just skip the number of bytes
if ( ! strict || str . charCodeAt ( strIdx ) === CharCodes . SEMI ) {
resultIdx = treeIdx ;
excess = 0 ;
}
// The mask is the number of bytes of the value, including the current byte.
const valueLength = ( masked >> 14 ) - 1 ;
if ( valueLength === 0 )
break ;
treeIdx += valueLength ;
}
}
if ( resultIdx !== 0 ) {
const valueLength = ( decodeTree [ resultIdx ] & BinTrieFlags . VALUE _LENGTH ) >> 14 ;
ret +=
valueLength === 1
? String . fromCharCode ( decodeTree [ resultIdx ] & ~ BinTrieFlags . VALUE _LENGTH )
: valueLength === 2
? String . fromCharCode ( decodeTree [ resultIdx + 1 ] )
: String . fromCharCode ( decodeTree [ resultIdx + 1 ] , decodeTree [ resultIdx + 2 ] ) ;
lastIdx = strIdx - excess + 1 ;
}
}
return ret + str . slice ( lastIdx ) ;
} ;
}
function determineBranch ( decodeTree , current , nodeIdx , char ) {
const branchCount = ( current & BinTrieFlags . BRANCH _LENGTH ) >> 7 ;
const jumpOffset = current & BinTrieFlags . JUMP _TABLE ;
// Case 1: Single branch encoded in jump offset
if ( branchCount === 0 ) {
return jumpOffset !== 0 && char === jumpOffset ? nodeIdx : - 1 ;
}
// Case 2: Multiple branches encoded in jump table
if ( jumpOffset ) {
const value = char - jumpOffset ;
return value < 0 || value >= branchCount
? - 1
: decodeTree [ nodeIdx + value ] - 1 ;
}
// Case 3: Multiple branches encoded in dictionary
// Binary search for the character.
let lo = nodeIdx ;
let hi = lo + branchCount - 1 ;
while ( lo <= hi ) {
const mid = ( lo + hi ) >>> 1 ;
const midVal = decodeTree [ mid ] ;
if ( midVal < char ) {
lo = mid + 1 ;
}
else if ( midVal > char ) {
hi = mid - 1 ;
}
else {
return decodeTree [ mid + branchCount ] ;
}
}
return - 1 ;
}
const htmlDecoder = getDecoder ( htmlDecodeTree ) ;
const xmlDecoder = getDecoder ( xmlDecodeTree ) ;
/ * *
* Decodes an HTML string , allowing for entities not terminated by a semi - colon .
*
* @ param str The string to decode .
* @ returns The decoded string .
* /
function decodeHTML ( str ) {
return htmlDecoder ( str , false ) ;
}
/ * *
* Decodes an XML string , requiring all entities to be terminated by a semi - colon .
*
* @ param str The string to decode .
* @ returns The decoded string .
* /
function decodeXML ( str ) {
return xmlDecoder ( str , true ) ;
}
/ *
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
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 .
* /
/ * *
* @ module verifications
* @ ignore
* /
/ * *
* @ function
* @ param { string } data
* @ param { object } params
* @ param { string } params . target
* @ param { string } params . claimFormat
* @ param { string } params . proofEncodingFormat
* @ param { string } [ params . claimRelation ]
* @ returns { Promise < boolean > }
* /
const containsProof = async ( data , params ) => {
const fingerprintFormatted = generateClaim ( params . target , params . claimFormat ) ;
const fingerprintURI = generateClaim ( params . target , ClaimFormat . URI ) ;
let result = false ;
// Decode eventual special entities
switch ( params . proofEncodingFormat ) {
case EntityEncodingFormat . HTML :
data = decodeHTML ( data ) ;
break
case EntityEncodingFormat . XML :
data = decodeXML ( data ) ;
break
case EntityEncodingFormat . PLAIN :
}
data = decodeHTML ( data ) ;
// Check for plaintext proof
result = data
// remove newlines and carriage returns
. replace ( /\r?\n|\r/g , '' )
// remove spaces
. replace ( /\s/g , '' )
// normalize
. toLowerCase ( )
// search for fingerprint
. indexOf ( fingerprintFormatted . toLowerCase ( ) ) !== - 1 ;
// Check for hashed proof
if ( ! result ) {
const hashRe = /\$(argon2(?:id|d|i)|2a|2b|2y)(?:\$[a-zA-Z0-9=+\-,./]+)+/g ;
let match ;
while ( ! result && ( match = hashRe . exec ( data ) ) != null ) {
let timeoutHandle ;
const timeoutPromise = new Promise ( ( resolve , reject ) => {
timeoutHandle = setTimeout (
( ) => {
resolve ( false ) ;
} , 1000
) ;
} ) ;
switch ( match [ 1 ] ) {
case '2a' :
case '2b' :
case '2y' :
try {
// Patch until promise.race properly works on WASM
if ( parseInt ( match [ 0 ] . split ( '$' ) [ 2 ] ) > 12 ) continue
const hashPromise = bcryptVerify ( {
2023-09-22 03:00:36 -06:00
password : fingerprintURI . toLowerCase ( ) ,
2023-07-09 04:05:21 -06:00
hash : match [ 0 ]
} )
. then ( result => result )
. catch ( _ => false ) ;
result = await Promise . race ( [ hashPromise , timeoutPromise ] ) . then ( ( result ) => {
clearTimeout ( timeoutHandle ) ;
return result
} ) ;
} catch ( err ) {
result = false ;
}
2023-09-22 03:00:36 -06:00
// Accept mixed-case fingerprints until deadline
if ( ! result ) {
try {
// Patch until promise.race properly works on WASM
if ( parseInt ( match [ 0 ] . split ( '$' ) [ 2 ] ) > 12 ) continue
const hashPromise = bcryptVerify ( {
password : fingerprintURI ,
hash : match [ 0 ]
} )
. then ( result => result )
. catch ( _ => false ) ;
result = await Promise . race ( [ hashPromise , timeoutPromise ] ) . then ( ( result ) => {
clearTimeout ( timeoutHandle ) ;
return result
} ) ;
} catch ( err ) {
result = false ;
}
}
2023-07-09 04:05:21 -06:00
break
case 'argon2' :
case 'argon2i' :
case 'argon2d' :
case 'argon2id' :
try {
const hashPromise = argon2Verify ( {
2023-09-22 03:00:36 -06:00
password : fingerprintURI . toLowerCase ( ) ,
2023-07-09 04:05:21 -06:00
hash : match [ 0 ]
} )
. then ( result => result )
. catch ( _ => false ) ;
result = await Promise . race ( [ hashPromise , timeoutPromise ] ) . then ( ( result ) => {
clearTimeout ( timeoutHandle ) ;
return result
} ) ;
} catch ( err ) {
result = false ;
}
2023-09-22 03:00:36 -06:00
// Accept mixed-case fingerprints until deadline
if ( ! result ) {
try {
const hashPromise = argon2Verify ( {
password : fingerprintURI ,
hash : match [ 0 ]
} )
. then ( result => result )
. catch ( _ => false ) ;
result = await Promise . race ( [ hashPromise , timeoutPromise ] ) . then ( ( result ) => {
clearTimeout ( timeoutHandle ) ;
return result
} ) ;
} catch ( err ) {
result = false ;
}
}
2023-07-09 04:05:21 -06:00
break
}
}
}
// Check for HTTP proof
if ( ! result ) {
const uris = getUriFromString ( data ) ;
for ( let index = 0 ; index < uris . length ; index ++ ) {
if ( result ) continue
const candidate = uris [ index ] ;
/** @type {URL} */
let candidateURL ;
try {
candidateURL = new URL ( candidate ) ;
} catch ( _ ) {
continue
}
if ( candidateURL . protocol !== 'https:' ) {
continue
}
// Using fetch -> axios doesn't find the ariadne-identity-proof header
/** @type {Response} */
const response = await fetch ( candidate , {
method : 'HEAD'
} )
. catch ( e => {
return undefined
} ) ;
if ( ! response ) continue
if ( response . status !== 200 ) continue
if ( ! response . headers . get ( 'ariadne-identity-proof' ) ) continue
result = response . headers . get ( 'ariadne-identity-proof' )
. toLowerCase ( )
. indexOf ( fingerprintURI . toLowerCase ( ) ) !== - 1 ;
}
}
return result
} ;
/ * *
* @ function
* @ param { any } proofData
* @ param { string [ ] } checkPath
* @ param { object } params
* @ param { string } params . target
* @ param { string } params . claimFormat
* @ param { string } params . proofEncodingFormat
* @ param { string } [ params . claimRelation ]
* @ returns { Promise < boolean > }
* /
const runJSON = async ( proofData , checkPath , params ) => {
if ( ! proofData ) {
return false
}
if ( Array . isArray ( proofData ) ) {
let result = false ;
for ( let index = 0 ; index < proofData . length ; index ++ ) {
const item = proofData [ index ] ;
if ( result ) {
continue
}
result = await runJSON ( item , checkPath , params ) ;
}
return result
}
if ( checkPath . length === 0 ) {
switch ( params . claimRelation ) {
case ClaimRelation . ONEOF :
return await containsProof ( proofData . join ( '|' ) , params )
case ClaimRelation . CONTAINS :
case ClaimRelation . EQUALS :
default :
return await containsProof ( proofData , params )
}
}
if ( typeof proofData === 'object' && ! ( checkPath [ 0 ] in proofData ) ) {
throw new Error ( 'err_json_structure_incorrect' )
}
return await runJSON (
proofData [ checkPath [ 0 ] ] ,
checkPath . slice ( 1 ) ,
params
)
} ;
/ * *
* Run the verification by finding the formatted fingerprint in the proof
* @ async
* @ param { object } proofData - The proof data
* @ param { import ( './serviceProvider.js' ) . ServiceProvider } claimData - The claim data
* @ param { string } fingerprint - The fingerprint
* @ returns { Promise < object > }
* /
async function run ( proofData , claimData , fingerprint ) {
const res = {
result : false ,
completed : false ,
errors : [ ]
} ;
switch ( claimData . proof . response . format ) {
case ProofFormat . JSON :
for ( let index = 0 ; index < claimData . proof . target . length ; index ++ ) {
const claimMethod = claimData . proof . target [ index ] ;
try {
res . result = res . result || await runJSON (
proofData ,
claimMethod . path ,
{
target : fingerprint ,
claimFormat : claimMethod . format ,
proofEncodingFormat : claimMethod . encoding ,
claimRelation : claimMethod . relation
}
) ;
} catch ( error ) {
res . errors . push ( error . message ? error . message : error ) ;
}
}
res . completed = true ;
break
case ProofFormat . TEXT :
for ( let index = 0 ; index < claimData . proof . target . length ; index ++ ) {
const claimMethod = claimData . proof . target [ index ] ;
try {
res . result = res . result || await containsProof (
proofData ,
{
target : fingerprint ,
claimFormat : claimMethod . format ,
proofEncodingFormat : claimMethod . encoding ,
claimRelation : claimMethod . relation
}
) ;
} catch ( error ) {
res . errors . push ( 'err_unknown_text_verification' ) ;
}
}
res . completed = true ;
break
}
// Reset the errors if one of the claim methods was successful
if ( res . result ) {
res . errors = [ ] ;
}
return res
}
var verifications = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
run : run
} ) ;
/ *
Copyright 2023 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 .
* /
/ * *
* A service provider matched to an identity claim
* @ class
* @ constructor
* @ public
* /
class ServiceProvider {
/ * *
* @ param { object } spObj
* /
constructor ( spObj ) {
/ * *
* Details about the service provider
* @ property { object }
* /
this . about = {
/ * *
* Identifier of the service provider ( no whitespace or symbols , lowercase )
* @ type { string }
* /
id : spObj . about . id ,
/ * *
* Full name of the service provider
* @ type { string }
* /
name : spObj . about . name ,
/ * *
* URL to the homepage of the service provider
* @ type { string | null }
* /
homepage : spObj . about . homepage || null
} ;
/ * *
* What the profile would look like if the match is correct
* @ property { object }
* /
this . profile = {
/ * *
* Profile name to be displayed
* @ type { string }
* /
display : spObj . profile . display ,
/ * *
* URI or URL for public access to the profile
* @ type { string }
* /
uri : spObj . profile . uri ,
/ * *
* URI or URL associated with the profile usually served as a QR code
* @ type { string | null }
* /
qr : spObj . profile . qr || null
} ;
/ * *
* Details from the claim matching process
* @ property { object }
* /
this . claim = {
/ * *
* Regular expression used to parse the URI
* @ type { string }
* /
uriRegularExpression : spObj . claim . uriRegularExpression ,
/ * *
* Whether this match automatically excludes other matches
* @ type { boolean }
* /
uriIsAmbiguous : spObj . claim . uriIsAmbiguous
} ;
/ * *
* Information for the proof verification process
* @ property { object }
* /
this . proof = {
/ * *
* Details to request the potential proof
* @ property { object }
* /
request : {
/ * *
* Location of the proof
2023-07-10 03:46:53 -06:00
* @ type { string | null }
2023-07-09 04:05:21 -06:00
* /
uri : spObj . proof . request . uri ,
/ * *
2023-07-10 03:46:53 -06:00
* Fetcher to be used to request the proof
2023-07-09 04:05:21 -06:00
* @ type { string }
* /
2023-07-10 03:46:53 -06:00
fetcher : spObj . proof . request . fetcher ,
2023-07-09 04:05:21 -06:00
/ * *
* Type of access restriction
* @ type { import ( './enums.js' ) . ProofAccessRestriction }
* /
accessRestriction : spObj . proof . request . accessRestriction ,
/ * *
* Data needed by the fetcher or proxy to request the proof
* @ type { object }
* /
data : spObj . proof . request . data
} ,
/ * *
* Details about the expected response
* @ property { object }
* /
response : {
/ * *
* Expected format of the proof
* @ type { import ( './enums.js' ) . ProofFormat }
* /
format : spObj . proof . response . format
} ,
/ * *
* Details about the target located in the response
* @ type { { format : import ( './enums.js' ) . ClaimFormat , encoding : import ( './enums.js' ) . EntityEncodingFormat , relation : import ( './enums.js' ) . ClaimRelation , path : string [ ] } [ ] }
* /
target : spObj . proof . target
} ;
}
2023-07-10 03:46:53 -06:00
/ * *
* Get a JSON representation of the ServiceProvider object
* @ function
* @ returns { object }
* /
toJSON ( ) {
return {
about : this . about ,
profile : this . profile ,
claim : this . claim ,
proof : this . proof
}
}
2023-07-09 04:05:21 -06:00
}
/ *
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
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 .
* /
2023-09-23 02:16:41 -06:00
const reURI$l = /^dns:([a-zA-Z0-9.\-_]*)(?:\?(.*))?/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-23 02:16:41 -06:00
function processURI$l ( uri ) {
const match = uri . match ( reURI$l ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
id : 'dns' ,
name : 'DNS'
} ,
profile : {
display : match [ 1 ] ,
uri : ` https:// ${ match [ 1 ] } ` ,
qr : null
} ,
claim : {
2023-09-23 02:16:41 -06:00
uriRegularExpression : reURI$l . toString ( ) ,
2023-07-09 04:05:21 -06:00
uriIsAmbiguous : false
} ,
proof : {
request : {
uri : null ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . DNS ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . SERVER ,
data : {
domain : match [ 1 ]
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ 'records' , 'txt' ]
} ]
}
} )
}
2023-09-23 02:16:41 -06:00
const tests$l = [
2023-07-09 04:05:21 -06:00
{
uri : 'dns:domain.org' ,
shouldMatch : true
} ,
{
uri : 'dns:domain.org?type=TXT' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org' ,
shouldMatch : false
}
] ;
var dns = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
2023-09-23 02:16:41 -06:00
processURI : processURI$l ,
reURI : reURI$l ,
tests : tests$l
2023-07-09 04:05:21 -06:00
} ) ;
/ *
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
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 .
* /
2023-09-23 02:16:41 -06:00
const reURI$k = /^irc:\/\/(.*)\/([a-zA-Z0-9\-[\]\\`_^{|}]*)/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-23 02:16:41 -06:00
function processURI$k ( uri ) {
const match = uri . match ( reURI$k ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
id : 'irc' ,
name : 'IRC'
} ,
profile : {
display : ` irc:// ${ match [ 1 ] } / ${ match [ 2 ] } ` ,
uri ,
qr : null
} ,
claim : {
2023-09-23 02:16:41 -06:00
uriRegularExpression : reURI$k . toString ( ) ,
2023-07-09 04:05:21 -06:00
uriIsAmbiguous : false
} ,
proof : {
request : {
uri : null ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . IRC ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . SERVER ,
data : {
domain : match [ 1 ] ,
nick : match [ 2 ]
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ ]
} ]
}
} )
}
2023-09-23 02:16:41 -06:00
const tests$k = [
2023-07-09 04:05:21 -06:00
{
uri : 'irc://chat.ircserver.org/Alice1' ,
shouldMatch : true
} ,
{
uri : 'irc://chat.ircserver.org/alice?param=123' ,
shouldMatch : true
} ,
{
uri : 'irc://chat.ircserver.org/alice_bob' ,
shouldMatch : true
} ,
{
uri : 'https://chat.ircserver.org/alice' ,
shouldMatch : false
}
] ;
var irc = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
2023-09-23 02:16:41 -06:00
processURI : processURI$k ,
reURI : reURI$k ,
tests : tests$k
2023-07-09 04:05:21 -06:00
} ) ;
/ *
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
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 .
* /
2023-09-23 02:16:41 -06:00
const reURI$j = /^xmpp:([a-zA-Z0-9.\-_]*)@([a-zA-Z0-9.\-_]*)(?:\?(.*))?/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-23 02:16:41 -06:00
function processURI$j ( uri ) {
const match = uri . match ( reURI$j ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
id : 'xmpp' ,
name : 'XMPP' ,
homepage : 'https://xmpp.org'
} ,
profile : {
display : ` ${ match [ 1 ] } @ ${ match [ 2 ] } ` ,
uri ,
qr : uri
} ,
claim : {
2023-09-23 02:16:41 -06:00
uriRegularExpression : reURI$j . toString ( ) ,
2023-07-09 04:05:21 -06:00
uriIsAmbiguous : false
} ,
proof : {
request : {
uri : null ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . XMPP ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . SERVER ,
data : {
id : ` ${ match [ 1 ] } @ ${ match [ 2 ] } `
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ ]
} ]
}
} )
}
2023-09-23 02:16:41 -06:00
const tests$j = [
2023-07-09 04:05:21 -06:00
{
uri : 'xmpp:alice@domain.org' ,
shouldMatch : true
} ,
{
uri : 'xmpp:alice@domain.org?omemo-sid-123456789=A1B2C3D4E5F6G7H8I9' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org' ,
shouldMatch : false
}
] ;
var xmpp = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
2023-09-23 02:16:41 -06:00
processURI : processURI$j ,
reURI : reURI$j ,
tests : tests$j
2023-07-09 04:05:21 -06:00
} ) ;
/ *
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
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 .
* /
2023-09-23 02:16:41 -06:00
const reURI$i = /^matrix:u\/(?:@)?([^@:]*:[^?]*)(\?.*)?/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-23 02:16:41 -06:00
function processURI$i ( uri ) {
const match = uri . match ( reURI$i ) ;
2023-07-09 04:05:21 -06:00
if ( ! match [ 2 ] ) {
return null
}
const params = new URLSearchParams ( match [ 2 ] ) ;
if ( ! ( params . has ( 'org.keyoxide.e' ) && params . has ( 'org.keyoxide.r' ) ) ) {
return null
}
const paramRoomId = ` ${ params . get ( 'org.keyoxide.r' ) [ 0 ] !== '!' ? '!' : '' } ${ params . get ( 'org.keyoxide.r' ) } ` ;
const paramEventId = ` ${ params . get ( 'org.keyoxide.e' ) [ 0 ] !== '$' ? '$' : '' } ${ params . get ( 'org.keyoxide.e' ) } ` ;
const profileUrl = ` https://matrix.to/#/@ ${ match [ 1 ] } ` ;
const eventUrl = ` https://matrix.to/#/ ${ paramRoomId } / ${ paramEventId } ` ;
return new ServiceProvider ( {
about : {
id : 'matrix' ,
name : 'Matrix' ,
homepage : 'https://matrix.org'
} ,
profile : {
display : ` @ ${ match [ 1 ] } ` ,
uri : profileUrl ,
qr : null
} ,
claim : {
2023-09-23 02:16:41 -06:00
uriRegularExpression : reURI$i . toString ( ) ,
2023-07-09 04:05:21 -06:00
uriIsAmbiguous : false
} ,
proof : {
request : {
uri : eventUrl ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . MATRIX ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . GRANTED ,
data : {
eventId : paramEventId ,
roomId : paramRoomId
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ 'content' , 'body' ]
} ]
}
} )
}
2023-09-23 02:16:41 -06:00
const tests$i = [
2023-07-09 04:05:21 -06:00
{
uri :
'matrix:u/alice:matrix.domain.org?org.keyoxide.r=123:domain.org&org.keyoxide.e=123' ,
shouldMatch : true
} ,
{
uri : 'matrix:u/alice:matrix.domain.org' ,
shouldMatch : true
} ,
{
uri :
'matrix:u/@alice:matrix.domain.org?org.keyoxide.r=!123:domain.org&org.keyoxide.e=$123' ,
shouldMatch : true
} ,
{
uri : 'xmpp:alice@domain.org' ,
shouldMatch : false
} ,
{
uri : 'https://domain.org/@alice' ,
shouldMatch : false
}
] ;
var matrix = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
2023-09-23 02:16:41 -06:00
processURI : processURI$i ,
reURI : reURI$i ,
tests : tests$i
2023-07-09 04:05:21 -06:00
} ) ;
/ *
Copyright 2022 Maximilian Siling
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 .
* /
2023-09-23 02:16:41 -06:00
const reURI$h = /https:\/\/t.me\/([A-Za-z0-9_]{5,32})\?proof=([A-Za-z0-9_]{5,32})/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-23 02:16:41 -06:00
function processURI$h ( uri ) {
const match = uri . match ( reURI$h ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
id : 'telegram' ,
name : 'Telegram' ,
homepage : 'https://telegram.org'
} ,
profile : {
display : ` @ ${ match [ 1 ] } ` ,
uri : ` https://t.me/ ${ match [ 1 ] } ` ,
qr : ` https://t.me/ ${ match [ 1 ] } `
} ,
claim : {
2023-09-23 02:16:41 -06:00
uriRegularExpression : reURI$h . toString ( ) ,
2023-07-09 04:05:21 -06:00
uriIsAmbiguous : false
} ,
proof : {
request : {
uri : ` https://t.me/ ${ match [ 2 ] } ` ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . TELEGRAM ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . GRANTED ,
data : {
user : match [ 1 ] ,
chat : match [ 2 ]
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . EQUALS ,
path : [ 'text' ]
} ]
}
} )
}
2023-09-23 02:16:41 -06:00
const tests$h = [
2023-07-09 04:05:21 -06:00
{
uri : 'https://t.me/alice?proof=foobar' ,
shouldMatch : true
} ,
{
uri : 'https://t.me/complex_user_1234?proof=complex_chat_1234' ,
shouldMatch : true
} ,
{
uri : 'https://t.me/foobar' ,
shouldMatch : false
} ,
{
uri : 'https://t.me/foobar?proof=' ,
shouldMatch : false
} ,
{
uri : 'https://t.me/?proof=foobar' ,
shouldMatch : false
}
] ;
var telegram = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
2023-09-23 02:16:41 -06:00
processURI : processURI$h ,
reURI : reURI$h ,
tests : tests$h
2023-07-09 04:05:21 -06:00
} ) ;
/ *
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
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 .
* /
2023-09-23 02:16:41 -06:00
const reURI$g = /^https:\/\/twitter\.com\/(.*)\/status\/([0-9]*)(?:\?.*)?/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-23 02:16:41 -06:00
function processURI$g ( uri ) {
const match = uri . match ( reURI$g ) ;
2023-07-09 04:05:21 -06:00
const urlsp = new URLSearchParams ( ) ;
urlsp . set ( 'url' , match [ 0 ] ) ;
urlsp . set ( 'omit_script' , '1' ) ;
return new ServiceProvider ( {
about : {
id : 'twitter' ,
name : 'Twitter' ,
homepage : 'https://twitter.com'
} ,
profile : {
display : ` @ ${ match [ 1 ] } ` ,
uri : ` https://twitter.com/ ${ match [ 1 ] } ` ,
qr : null
} ,
claim : {
2023-09-23 02:16:41 -06:00
uriRegularExpression : reURI$g . toString ( ) ,
2023-07-09 04:05:21 -06:00
uriIsAmbiguous : false
} ,
proof : {
request : {
uri ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . HTTP ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . NOCORS ,
data : {
// Returns an oembed json object with the tweet content in html form
url : ` https://publish.twitter.com/oembed? ${ urlsp } ` ,
format : ProofFormat . JSON
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ 'html' ]
} ]
}
} )
}
2023-09-23 02:16:41 -06:00
const tests$g = [
2023-07-09 04:05:21 -06:00
{
uri : 'https://twitter.com/alice/status/1234567890123456789' ,
shouldMatch : true
} ,
{
uri : 'https://twitter.com/alice/status/1234567890123456789/' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/alice/status/1234567890123456789' ,
shouldMatch : false
}
] ;
var twitter = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
2023-09-23 02:16:41 -06:00
processURI : processURI$g ,
reURI : reURI$g ,
tests : tests$g
2023-07-09 04:05:21 -06:00
} ) ;
/ *
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
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 .
* /
2023-09-23 02:16:41 -06:00
const reURI$f = /^https:\/\/(?:www\.)?reddit\.com\/user\/(.*)\/comments\/(.*)\/(.*)\/?/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-23 02:16:41 -06:00
function processURI$f ( uri ) {
const match = uri . match ( reURI$f ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
id : 'reddit' ,
name : 'Reddit' ,
homepage : 'https://reddit.com'
} ,
profile : {
display : match [ 1 ] ,
uri : ` https://www.reddit.com/user/ ${ match [ 1 ] } ` ,
qr : null
} ,
claim : {
2023-09-23 02:16:41 -06:00
uriRegularExpression : reURI$f . toString ( ) ,
2023-07-09 04:05:21 -06:00
uriIsAmbiguous : false
} ,
proof : {
request : {
uri ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . HTTP ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . NOCORS ,
data : {
url : ` https://www.reddit.com/user/ ${ match [ 1 ] } /comments/ ${ match [ 2 ] } .json ` ,
format : ProofFormat . JSON
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ 'data' , 'children' , 'data' , 'selftext' ]
} ]
}
} )
}
2023-09-23 02:16:41 -06:00
const tests$f = [
2023-07-09 04:05:21 -06:00
{
uri : 'https://www.reddit.com/user/Alice/comments/123456/post' ,
shouldMatch : true
} ,
{
uri : 'https://www.reddit.com/user/Alice/comments/123456/post/' ,
shouldMatch : true
} ,
{
uri : 'https://reddit.com/user/Alice/comments/123456/post' ,
shouldMatch : true
} ,
{
uri : 'https://reddit.com/user/Alice/comments/123456/post/' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/user/Alice/comments/123456/post' ,
shouldMatch : false
}
] ;
var reddit = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
2023-09-23 02:16:41 -06:00
processURI : processURI$f ,
reURI : reURI$f ,
tests : tests$f
2023-07-09 04:05:21 -06:00
} ) ;
/ *
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
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 .
* /
2023-09-23 02:16:41 -06:00
const reURI$e = /^https:\/\/liberapay\.com\/(.*)\/?/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-23 02:16:41 -06:00
function processURI$e ( uri ) {
const match = uri . match ( reURI$e ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
id : 'liberapay' ,
name : 'Liberapay' ,
homepage : 'https://liberapay.com'
} ,
profile : {
display : match [ 1 ] ,
uri ,
qr : null
} ,
claim : {
2023-09-23 02:16:41 -06:00
uriRegularExpression : reURI$e . toString ( ) ,
2023-07-09 04:05:21 -06:00
uriIsAmbiguous : false
} ,
proof : {
request : {
uri ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . HTTP ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . NONE ,
data : {
url : ` https://liberapay.com/ ${ match [ 1 ] } /public.json ` ,
format : ProofFormat . JSON
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ 'statements' , 'content' ]
} ]
}
} )
}
2023-09-23 02:16:41 -06:00
const tests$e = [
2023-07-09 04:05:21 -06:00
{
uri : 'https://liberapay.com/alice' ,
shouldMatch : true
} ,
{
uri : 'https://liberapay.com/alice/' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/alice' ,
shouldMatch : false
}
] ;
var liberapay = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
2023-09-23 02:16:41 -06:00
processURI : processURI$e ,
reURI : reURI$e ,
tests : tests$e
2023-07-09 04:05:21 -06:00
} ) ;
/ *
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
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 .
* /
2023-09-23 02:16:41 -06:00
const reURI$d = /^https:\/\/lichess\.org\/@\/(.*)\/?/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-23 02:16:41 -06:00
function processURI$d ( uri ) {
const match = uri . match ( reURI$d ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
2023-10-03 04:05:09 -06:00
id : 'lichess' ,
name : 'Lichess' ,
homepage : 'https://lichess.org'
2023-07-09 04:05:21 -06:00
} ,
profile : {
display : match [ 1 ] ,
uri ,
qr : null
} ,
claim : {
2023-09-23 02:16:41 -06:00
uriRegularExpression : reURI$d . toString ( ) ,
2023-07-09 04:05:21 -06:00
uriIsAmbiguous : false
} ,
proof : {
request : {
uri : ` https://lichess.org/api/user/ ${ match [ 1 ] } ` ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . HTTP ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . NONE ,
data : {
url : ` https://lichess.org/api/user/ ${ match [ 1 ] } ` ,
format : ProofFormat . JSON
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . FINGERPRINT ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ 'profile' , 'links' ]
} ]
}
} )
}
2023-09-23 02:16:41 -06:00
const tests$d = [
2023-07-09 04:05:21 -06:00
{
uri : 'https://lichess.org/@/Alice' ,
shouldMatch : true
} ,
{
uri : 'https://lichess.org/@/Alice/' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/@/Alice' ,
shouldMatch : false
}
] ;
var lichess = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
2023-09-23 02:16:41 -06:00
processURI : processURI$d ,
reURI : reURI$d ,
tests : tests$d
2023-07-09 04:05:21 -06:00
} ) ;
/ *
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
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 .
* /
2023-09-23 02:16:41 -06:00
const reURI$c = /^https:\/\/news\.ycombinator\.com\/user\?id=(.*)\/?/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-23 02:16:41 -06:00
function processURI$c ( uri ) {
const match = uri . match ( reURI$c ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
id : 'hackernews' ,
name : 'Hacker News' ,
homepage : 'https://news.ycombinator.com'
} ,
profile : {
display : match [ 1 ] ,
uri ,
qr : null
} ,
claim : {
2023-09-23 02:16:41 -06:00
uriRegularExpression : reURI$c . toString ( ) ,
2023-07-09 04:05:21 -06:00
uriIsAmbiguous : false
} ,
proof : {
request : {
uri : ` https://hacker-news.firebaseio.com/v0/user/ ${ match [ 1 ] } .json ` ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . HTTP ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . NOCORS ,
data : {
url : ` https://hacker-news.firebaseio.com/v0/user/ ${ match [ 1 ] } .json ` ,
format : ProofFormat . JSON
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . HTML ,
relation : ClaimRelation . CONTAINS ,
path : [ 'about' ]
} ]
}
} )
}
2023-09-23 02:16:41 -06:00
const tests$c = [
2023-07-09 04:05:21 -06:00
{
uri : 'https://news.ycombinator.com/user?id=Alice' ,
shouldMatch : true
} ,
{
uri : 'https://news.ycombinator.com/user?id=Alice/' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/user?id=Alice' ,
shouldMatch : false
}
] ;
var hackernews = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
2023-09-23 02:16:41 -06:00
processURI : processURI$c ,
reURI : reURI$c ,
tests : tests$c
2023-07-09 04:05:21 -06:00
} ) ;
/ *
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
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 .
* /
2023-09-23 02:16:41 -06:00
const reURI$b = /^https:\/\/lobste\.rs\/u\/(.*)\/?/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-23 02:16:41 -06:00
function processURI$b ( uri ) {
const match = uri . match ( reURI$b ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
id : 'lobsters' ,
name : 'Lobsters' ,
homepage : 'https://lobste.rs'
} ,
profile : {
display : match [ 1 ] ,
uri ,
qr : null
} ,
claim : {
2023-09-23 02:16:41 -06:00
uriRegularExpression : reURI$b . toString ( ) ,
2023-07-09 04:05:21 -06:00
uriIsAmbiguous : false
} ,
proof : {
request : {
uri : ` https://lobste.rs/u/ ${ match [ 1 ] } .json ` ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . HTTP ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . NOCORS ,
data : {
url : ` https://lobste.rs/u/ ${ match [ 1 ] } .json ` ,
format : ProofFormat . JSON
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ 'about' ]
} ]
}
} )
}
2023-09-23 02:16:41 -06:00
const tests$b = [
2023-07-09 04:05:21 -06:00
{
uri : 'https://lobste.rs/u/Alice' ,
shouldMatch : true
} ,
{
uri : 'https://lobste.rs/u/Alice/' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/u/Alice' ,
shouldMatch : false
}
] ;
var lobsters = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
2023-09-23 02:16:41 -06:00
processURI : processURI$b ,
reURI : reURI$b ,
tests : tests$b
2023-07-09 04:05:21 -06:00
} ) ;
/ *
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
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 .
* /
2023-09-23 02:16:41 -06:00
const reURI$a = /^https:\/\/(.*)\/(.*)\/(.*)\/?/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-23 02:16:41 -06:00
function processURI$a ( uri ) {
const match = uri . match ( reURI$a ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
id : 'forem' ,
name : 'Forem' ,
homepage : 'https://www.forem.com'
} ,
profile : {
display : ` ${ match [ 2 ] } @ ${ match [ 1 ] } ` ,
uri : ` https:// ${ match [ 1 ] } / ${ match [ 2 ] } ` ,
qr : null
} ,
claim : {
2023-09-23 02:16:41 -06:00
uriRegularExpression : reURI$a . toString ( ) . toString ( ) ,
2023-07-09 04:05:21 -06:00
uriIsAmbiguous : true
} ,
proof : {
request : {
uri ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . HTTP ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . NOCORS ,
data : {
url : ` https:// ${ match [ 1 ] } /api/articles/ ${ match [ 2 ] } / ${ match [ 3 ] } ` ,
format : ProofFormat . JSON
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ 'body_markdown' ]
} ]
}
} )
}
2023-09-23 02:16:41 -06:00
const tests$a = [
2023-07-09 04:05:21 -06:00
{
uri : 'https://domain.org/alice/post' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/alice/post/' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/alice' ,
shouldMatch : false
}
] ;
var forem = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
2023-09-23 02:16:41 -06:00
processURI : processURI$a ,
reURI : reURI$a ,
tests : tests$a
} ) ;
/ *
Copyright 2023 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$9 = /^https:\/\/(.*)\/(.*)\/(.*)\/?/ ;
/ * *
* @ function
* @ param { string } uri
* /
function processURI$9 ( uri ) {
const match = uri . match ( reURI$9 ) ;
return new ServiceProvider ( {
about : {
id : 'forgejo' ,
name : 'Forgejo' ,
homepage : 'https://forgejo.org'
} ,
profile : {
display : ` ${ match [ 2 ] } @ ${ match [ 1 ] } ` ,
uri : ` https:// ${ match [ 1 ] } / ${ match [ 2 ] } ` ,
qr : null
} ,
claim : {
uriRegularExpression : reURI$9 . toString ( ) ,
uriIsAmbiguous : true
} ,
proof : {
request : {
uri ,
fetcher : Fetcher . HTTP ,
accessRestriction : ProofAccessRestriction . NOCORS ,
data : {
url : ` https:// ${ match [ 1 ] } /api/v1/repos/ ${ match [ 2 ] } / ${ match [ 3 ] } ` ,
format : ProofFormat . JSON
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . EQUALS ,
path : [ 'description' ]
} ]
}
} )
}
const functions$1 = {
validate : async ( /** @type {ServiceProvider} */ claimData , proofData , opts ) => {
const url = ` https:// ${ new URL ( claimData . proof . request . uri ) . hostname } /api/forgejo/v1/version ` ;
const forgejoData = await fetcher _ _namespace . http . fn ( { url , format : ProofFormat . JSON } , opts ) ;
return forgejoData && 'version' in forgejoData
}
} ;
const tests$9 = [
{
uri : 'https://domain.org/alice/forgejo_proof' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/alice/forgejo_proof/' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/alice/other_proof' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/alice' ,
shouldMatch : false
}
] ;
var forgejo = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
functions : functions$1 ,
2023-07-09 04:05:21 -06:00
processURI : processURI$9 ,
reURI : reURI$9 ,
tests : tests$9
} ) ;
/ *
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
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$8 = /^https:\/\/(.*)\/(.*)\/(.*)\/?/ ;
/ * *
* @ function
* @ param { string } uri
* /
function processURI$8 ( uri ) {
const match = uri . match ( reURI$8 ) ;
return new ServiceProvider ( {
about : {
id : 'gitea' ,
name : 'Gitea' ,
homepage : 'https://about.gitea.com'
} ,
profile : {
2023-09-21 06:49:15 -06:00
display : ` ${ match [ 2 ] } @ ${ match [ 1 ] } ` ,
uri : ` https:// ${ match [ 1 ] } / ${ match [ 2 ] } ` ,
qr : null
} ,
claim : {
uriRegularExpression : reURI$8 . toString ( ) ,
uriIsAmbiguous : true
} ,
proof : {
request : {
uri ,
fetcher : Fetcher . HTTP ,
accessRestriction : ProofAccessRestriction . NOCORS ,
data : {
url : ` https:// ${ match [ 1 ] } /api/v1/repos/ ${ match [ 2 ] } / ${ match [ 3 ] } ` ,
format : ProofFormat . JSON
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . EQUALS ,
path : [ 'description' ]
} ]
}
} )
}
const tests$8 = [
{
uri : 'https://domain.org/alice/gitea_proof' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/alice/gitea_proof/' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/alice/other_proof' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/alice' ,
shouldMatch : false
}
] ;
var gitea = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
processURI : processURI$8 ,
reURI : reURI$8 ,
tests : tests$8
} ) ;
/ *
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
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$7 = /^https:\/\/(.*)\/(.*)\/gitlab_proof\/?/ ;
/ * *
* @ function
* @ param { string } uri
* /
function processURI$7 ( uri ) {
const match = uri . match ( reURI$7 ) ;
return new ServiceProvider ( {
about : {
id : 'gitlab' ,
name : 'GitLab' ,
homepage : 'https://about.gitlab.com'
} ,
profile : {
display : ` ${ match [ 2 ] } @ ${ match [ 1 ] } ` ,
uri : ` https:// ${ match [ 1 ] } / ${ match [ 2 ] } ` ,
qr : null
} ,
claim : {
uriRegularExpression : reURI$7 . toString ( ) ,
uriIsAmbiguous : true
} ,
proof : {
uri ,
request : {
fetcher : Fetcher . HTTP ,
accessRestriction : ProofAccessRestriction . NONE ,
data : {
url : ` https:// ${ match [ 1 ] } /api/v4/projects/ ${ match [ 2 ] } %2Fgitlab_proof ` ,
format : ProofFormat . JSON
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . EQUALS ,
path : [ 'description' ]
} ]
}
} )
}
const tests$7 = [
{
uri : 'https://gitlab.domain.org/alice/gitlab_proof' ,
shouldMatch : true
} ,
{
uri : 'https://gitlab.domain.org/alice/gitlab_proof/' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/alice/other_proof' ,
shouldMatch : false
}
] ;
var gitlab = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
processURI : processURI$7 ,
reURI : reURI$7 ,
tests : tests$7
} ) ;
/ *
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
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$6 = /^https:\/\/gist\.github\.com\/(.*)\/(.*)\/?/ ;
/ * *
* @ function
* @ param { string } uri
* /
function processURI$6 ( uri ) {
const match = uri . match ( reURI$6 ) ;
return new ServiceProvider ( {
about : {
id : 'github' ,
name : 'GitHub' ,
homepage : 'https://github.com'
} ,
profile : {
display : match [ 1 ] ,
uri : ` https://github.com/ ${ match [ 1 ] } ` ,
qr : null
} ,
claim : {
uriRegularExpression : reURI$6 . toString ( ) ,
uriIsAmbiguous : false
} ,
proof : {
request : {
uri ,
fetcher : Fetcher . HTTP ,
accessRestriction : ProofAccessRestriction . NONE ,
data : {
url : ` https://api.github.com/gists/ ${ match [ 2 ] } ` ,
format : ProofFormat . JSON
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ 'files' , 'openpgp.md' , 'content' ]
} ]
}
} )
}
const tests$6 = [
{
uri : 'https://gist.github.com/Alice/123456789' ,
shouldMatch : true
} ,
{
uri : 'https://gist.github.com/Alice/123456789/' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/Alice/123456789' ,
shouldMatch : false
}
] ;
var github = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
processURI : processURI$6 ,
reURI : reURI$6 ,
tests : tests$6
} ) ;
/ *
Copyright 2022 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$5 = /^https:\/\/(.*)\/?/ ;
/ * *
* @ function
* @ param { string } uri
* @ returns { ServiceProvider }
* /
function processURI$5 ( uri ) {
return new ServiceProvider ( {
about : {
id : 'activitypub' ,
name : 'ActivityPub' ,
homepage : 'https://activitypub.rocks'
} ,
profile : {
display : uri ,
uri ,
2023-07-09 04:05:21 -06:00
qr : null
} ,
claim : {
2023-09-21 06:49:15 -06:00
uriRegularExpression : reURI$5 . toString ( ) . toString ( ) ,
2023-07-09 04:05:21 -06:00
uriIsAmbiguous : true
} ,
proof : {
request : {
uri ,
2023-09-21 06:49:15 -06:00
fetcher : Fetcher . ACTIVITYPUB ,
accessRestriction : ProofAccessRestriction . NONE ,
2023-07-09 04:05:21 -06:00
data : {
2023-09-21 06:49:15 -06:00
url : uri
2023-07-09 04:05:21 -06:00
}
} ,
response : {
format : ProofFormat . JSON
} ,
2023-09-21 06:49:15 -06:00
target : [
{
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ 'summary' ]
} ,
{
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ 'attachment' , 'value' ]
} ,
{
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ 'content' ]
}
]
2023-07-09 04:05:21 -06:00
}
} )
}
2023-09-21 06:49:15 -06:00
const functions = {
postprocess : async ( /** @type {ServiceProvider} */ claimData , proofData , opts ) => {
switch ( proofData . result . type ) {
case 'Note' : {
claimData . profile . uri = proofData . result . attributedTo ;
claimData . profile . display = proofData . result . attributedTo ;
const personData = await fetcher _ _namespace . activitypub . fn ( { url : proofData . result . attributedTo } , opts )
. catch ( _ => null ) ;
if ( personData ) {
claimData . profile . display = ` @ ${ personData . preferredUsername } @ ${ new URL ( claimData . proof . request . uri ) . hostname } ` ;
}
break
}
case 'Person' :
claimData . profile . display = ` @ ${ proofData . result . preferredUsername } @ ${ new URL ( claimData . proof . request . uri ) . hostname } ` ;
break
}
// Attempt to fetch and process the instance's NodeInfo data
const nodeinfo = await _processNodeinfo ( new URL ( claimData . proof . request . uri ) . hostname ) ;
if ( nodeinfo ) {
claimData . about . name = nodeinfo . software . name ;
claimData . about . id = nodeinfo . software . name ;
claimData . about . homepage = nodeinfo . software . homepage ;
}
return { claimData , proofData }
}
} ;
const _processNodeinfo = async ( /** @type {string} */ domain ) => {
const nodeinfoRef = await fetch ( ` https:// ${ domain } /.well-known/nodeinfo ` )
. then ( res => {
if ( res . status !== 200 ) {
throw new Error ( 'HTTP Status was not 200' )
}
return res . json ( )
} )
. catch ( _ => {
return null
} ) ;
if ( ! nodeinfoRef ) return null
// NodeInfo version 2.1
2023-07-09 04:05:21 -06:00
{
2023-09-21 06:49:15 -06:00
const nodeinfo = nodeinfoRef . links . find ( x => { return x . rel === 'http://nodeinfo.diaspora.software/ns/schema/2.1' } ) ;
if ( nodeinfo ) {
return await fetch ( nodeinfo . href )
. then ( res => {
if ( res . status !== 200 ) {
throw new Error ( 'HTTP Status was not 200' )
}
return res . json ( )
} )
. then ( res => {
return {
software : {
name : res . software . name ,
version : res . software . version ,
homepage : res . software . homepage || 'https://activitypub.rocks'
}
}
} )
. catch ( _ => {
return null
} )
}
}
// NodeInfo version 2.0
{
const nodeinfo = nodeinfoRef . links . find ( x => { return x . rel === 'http://nodeinfo.diaspora.software/ns/schema/2.0' } ) ;
if ( nodeinfo ) {
return await fetch ( nodeinfo . href )
. then ( res => {
if ( res . status !== 200 ) {
throw new Error ( 'HTTP Status was not 200' )
}
return res . json ( )
} )
. then ( res => {
return {
software : {
name : res . software . name ,
version : res . software . version ,
homepage : 'https://activitypub.rocks'
}
}
} )
. catch ( _ => {
return null
} )
}
}
// NodeInfo version 1.1
{
const nodeinfo = nodeinfoRef . links . find ( x => { return x . rel === 'http://nodeinfo.diaspora.software/ns/schema/1.1' } ) ;
if ( nodeinfo ) {
return await fetch ( nodeinfo . href )
. then ( res => {
if ( res . status !== 200 ) {
throw new Error ( 'HTTP Status was not 200' )
}
return res . json ( )
} )
. then ( res => {
return {
software : {
name : res . software . name ,
version : res . software . version ,
homepage : 'https://activitypub.rocks'
}
}
} )
. catch ( _ => {
return null
} )
}
}
// NodeInfo version 1.0
{
const nodeinfo = nodeinfoRef . links . find ( x => { return x . rel === 'http://nodeinfo.diaspora.software/ns/schema/1.0' } ) ;
if ( nodeinfo ) {
return await fetch ( nodeinfo . href )
. then ( res => {
if ( res . status !== 200 ) {
throw new Error ( 'HTTP Status was not 200' )
}
return res . json ( )
} )
. then ( res => {
return {
software : {
name : res . software . name ,
version : res . software . version ,
homepage : 'https://activitypub.rocks'
}
}
} )
. catch ( _ => {
return null
} )
}
}
} ;
const tests$5 = [
{
uri : 'https://domain.org' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://domain.org/@/alice/' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://domain.org/@alice' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://domain.org/@alice/123456' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/u/alice/' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/users/alice/' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/users/alice/123456' ,
shouldMatch : true
} ,
{
uri : 'http://domain.org/alice' ,
2023-07-09 04:05:21 -06:00
shouldMatch : false
}
] ;
2023-09-21 06:49:15 -06:00
var activitypub = /*#__PURE__*/ Object . freeze ( {
2023-07-09 04:05:21 -06:00
_ _proto _ _ : null ,
2023-09-21 06:49:15 -06:00
functions : functions ,
processURI : processURI$5 ,
reURI : reURI$5 ,
tests : tests$5
2023-07-09 04:05:21 -06:00
} ) ;
/ *
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
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 .
* /
2023-09-21 06:49:15 -06:00
const reURI$4 = /^https:\/\/(.*)\/u\/(.*)\/?/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
2023-09-21 06:49:15 -06:00
* @ returns { ServiceProvider }
2023-07-09 04:05:21 -06:00
* /
2023-09-21 06:49:15 -06:00
function processURI$4 ( uri ) {
const match = uri . match ( reURI$4 ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
2023-09-21 06:49:15 -06:00
id : 'discourse' ,
name : 'Discourse' ,
homepage : 'https://www.discourse.org'
2023-07-09 04:05:21 -06:00
} ,
profile : {
display : ` ${ match [ 2 ] } @ ${ match [ 1 ] } ` ,
2023-09-21 06:49:15 -06:00
uri ,
2023-07-09 04:05:21 -06:00
qr : null
} ,
claim : {
2023-09-21 06:49:15 -06:00
uriRegularExpression : reURI$4 . toString ( ) . toString ( ) ,
2023-07-09 04:05:21 -06:00
uriIsAmbiguous : true
} ,
proof : {
request : {
2023-09-21 06:49:15 -06:00
uri ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . HTTP ,
2023-09-21 06:49:15 -06:00
accessRestriction : ProofAccessRestriction . NOCORS ,
2023-07-09 04:05:21 -06:00
data : {
2023-09-21 06:49:15 -06:00
url : ` https:// ${ match [ 1 ] } /u/ ${ match [ 2 ] } .json ` ,
2023-07-09 04:05:21 -06:00
format : ProofFormat . JSON
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
2023-09-21 06:49:15 -06:00
relation : ClaimRelation . CONTAINS ,
path : [ 'user' , 'bio_raw' ]
2023-07-09 04:05:21 -06:00
} ]
}
} )
}
2023-09-21 06:49:15 -06:00
const tests$4 = [
2023-07-09 04:05:21 -06:00
{
2023-09-21 06:49:15 -06:00
uri : 'https://domain.org/u/alice' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://domain.org/u/alice/' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://domain.org/alice' ,
2023-07-09 04:05:21 -06:00
shouldMatch : false
}
] ;
2023-09-21 06:49:15 -06:00
var discourse = /*#__PURE__*/ Object . freeze ( {
2023-07-09 04:05:21 -06:00
_ _proto _ _ : null ,
2023-09-21 06:49:15 -06:00
processURI : processURI$4 ,
reURI : reURI$4 ,
tests : tests$4
2023-07-09 04:05:21 -06:00
} ) ;
/ *
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
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 .
* /
2023-09-21 06:49:15 -06:00
const reURI$3 = /^https:\/\/(.*)/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-21 06:49:15 -06:00
function processURI$3 ( uri ) {
const match = uri . match ( reURI$3 ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
2023-09-21 06:49:15 -06:00
id : 'owncast' ,
name : 'Owncast' ,
homepage : 'https://owncast.online'
2023-07-09 04:05:21 -06:00
} ,
profile : {
display : match [ 1 ] ,
2023-09-21 06:49:15 -06:00
uri ,
2023-07-09 04:05:21 -06:00
qr : null
} ,
claim : {
2023-09-21 06:49:15 -06:00
uriRegularExpression : reURI$3 . toString ( ) ,
uriIsAmbiguous : true
2023-07-09 04:05:21 -06:00
} ,
proof : {
request : {
2023-09-21 06:49:15 -06:00
uri : ` ${ uri } /api/config ` ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . HTTP ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . NONE ,
data : {
2023-09-21 06:49:15 -06:00
url : ` ${ uri } /api/config ` ,
2023-07-09 04:05:21 -06:00
format : ProofFormat . JSON
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
2023-09-21 06:49:15 -06:00
format : ClaimFormat . FINGERPRINT ,
2023-07-09 04:05:21 -06:00
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
2023-09-21 06:49:15 -06:00
path : [ 'socialHandles' , 'url' ]
2023-07-09 04:05:21 -06:00
} ]
}
} )
}
2023-09-21 06:49:15 -06:00
const tests$3 = [
2023-07-09 04:05:21 -06:00
{
2023-09-21 06:49:15 -06:00
uri : 'https://live.domain.org' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://live.domain.org/' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://domain.org/live' ,
shouldMatch : true
} ,
{
uri : 'https://domain.org/live/' ,
shouldMatch : true
2023-07-09 04:05:21 -06:00
}
] ;
2023-09-21 06:49:15 -06:00
var owncast = /*#__PURE__*/ Object . freeze ( {
2023-07-09 04:05:21 -06:00
_ _proto _ _ : null ,
2023-09-21 06:49:15 -06:00
processURI : processURI$3 ,
reURI : reURI$3 ,
tests : tests$3
2023-07-09 04:05:21 -06:00
} ) ;
/ *
Copyright 2022 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 .
* /
2023-09-21 06:49:15 -06:00
const reURI$2 = /^https:\/\/(.*(?:askubuntu|mathoverflow|serverfault|stackapps|stackoverflow|superuser)|.+\.stackexchange)\.com\/users\/(\d+)/ ;
const reStackExchange = /\.stackexchange$/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-21 06:49:15 -06:00
function processURI$2 ( uri ) {
const [ , domain , id ] = uri . match ( reURI$2 ) ;
const site = domain . replace ( reStackExchange , '' ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
2023-09-21 06:49:15 -06:00
id : 'stackexchange' ,
name : 'Stack Exchange' ,
homepage : 'https://stackexchange.com'
2023-07-09 04:05:21 -06:00
} ,
profile : {
2023-09-21 06:49:15 -06:00
display : ` ${ id } @ ${ site } ` ,
2023-07-09 04:05:21 -06:00
uri ,
qr : null
} ,
claim : {
2023-09-21 06:49:15 -06:00
uriRegularExpression : reURI$2 . toString ( ) ,
uriIsAmbiguous : false
2023-07-09 04:05:21 -06:00
} ,
proof : {
request : {
2023-09-21 06:49:15 -06:00
uri : ` https:// ${ domain } .com/users/ ${ id } ?tab=profile ` ,
fetcher : Fetcher . HTTP ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . NONE ,
data : {
2023-09-21 06:49:15 -06:00
url : ` https://api.stackexchange.com/2.3/users/ ${ id } ?site= ${ site } &filter=!AH)b5JqVyImf ` ,
format : ProofFormat . JSON
2023-07-09 04:05:21 -06:00
}
} ,
response : {
format : ProofFormat . JSON
} ,
2023-09-21 06:49:15 -06:00
target : [ {
format : ClaimFormat . URI ,
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
path : [ 'items' , 'about_me' ]
} ]
2023-09-18 09:46:54 -06:00
}
2023-09-21 06:49:15 -06:00
} )
}
2023-09-18 09:46:54 -06:00
2023-09-21 06:49:15 -06:00
const tests$2 = [
2023-07-09 04:05:21 -06:00
{
2023-09-21 06:49:15 -06:00
uri : 'https://stackoverflow.com/users/1234' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://stackoverflow.com/users/1234/alice' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://stackoverflow.com/users/1234?tab=topactivity' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://stackoverflow.com/users/1234/alice?tab=profile' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://meta.stackoverflow.com/users/1234' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://pt.stackoverflow.com/users/1234' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://pt.meta.stackoverflow.com/users/1234' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://serverfault.com/users/1234' ,
shouldMatch : true
} ,
{
uri : 'https://meta.stackexchange.com/users/1234' ,
shouldMatch : true
} ,
{
uri : 'https://gaming.meta.stackexchange.com/users/1234' ,
shouldMatch : true
} ,
{
uri : 'https://stackexchange.com/users/1234' ,
shouldMatch : false
} ,
{
uri : 'https://domain.com/users/1234' ,
shouldMatch : false
} ,
{
uri : 'https://meta.domain.com/users/1234' ,
2023-07-09 04:05:21 -06:00
shouldMatch : false
}
2023-09-21 06:49:15 -06:00
2023-07-09 04:05:21 -06:00
] ;
2023-09-21 06:49:15 -06:00
var stackexchange = /*#__PURE__*/ Object . freeze ( {
2023-07-09 04:05:21 -06:00
_ _proto _ _ : null ,
2023-09-21 06:49:15 -06:00
processURI : processURI$2 ,
reURI : reURI$2 ,
tests : tests$2
2023-07-09 04:05:21 -06:00
} ) ;
/ *
2023-09-21 06:49:15 -06:00
Copyright 2023 Yarmo Mackenbach
2023-07-09 04:05:21 -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 .
* /
2023-09-21 06:49:15 -06:00
const reURI$1 = /^https:\/\/keybase.io\/(.*)\/?/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-21 06:49:15 -06:00
function processURI$1 ( uri ) {
const match = uri . match ( reURI$1 ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
2023-10-03 04:05:09 -06:00
id : 'keybase' ,
name : 'keybase' ,
homepage : 'https://keybase.io'
2023-07-09 04:05:21 -06:00
} ,
profile : {
2023-09-21 06:49:15 -06:00
display : match [ 1 ] ,
2023-07-09 04:05:21 -06:00
uri ,
qr : null
} ,
claim : {
2023-09-21 06:49:15 -06:00
uriRegularExpression : reURI$1 . toString ( ) ,
uriIsAmbiguous : false
2023-07-09 04:05:21 -06:00
} ,
proof : {
request : {
2023-09-21 06:49:15 -06:00
uri : ` https://keybase.io/_/api/1.0/user/lookup.json?username= ${ match [ 1 ] } ` ,
2023-07-10 03:46:53 -06:00
fetcher : Fetcher . HTTP ,
2023-07-09 04:05:21 -06:00
accessRestriction : ProofAccessRestriction . NOCORS ,
data : {
2023-09-21 06:49:15 -06:00
url : ` https://keybase.io/_/api/1.0/user/lookup.json?username= ${ match [ 1 ] } ` ,
2023-07-09 04:05:21 -06:00
format : ProofFormat . JSON
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
2023-09-21 06:49:15 -06:00
format : ClaimFormat . FINGERPRINT ,
2023-07-09 04:05:21 -06:00
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
2023-09-21 06:49:15 -06:00
path : [ 'them' , 'public_keys' , 'primary' , 'key_fingerprint' ]
2023-07-09 04:05:21 -06:00
} ]
}
} )
}
2023-09-21 06:49:15 -06:00
const tests$1 = [
2023-07-09 04:05:21 -06:00
{
2023-09-21 06:49:15 -06:00
uri : 'https://keybase.io/Alice' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://keybase.io/Alice/' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://domain.org/Alice' ,
2023-07-09 04:05:21 -06:00
shouldMatch : false
}
] ;
2023-09-21 06:49:15 -06:00
var keybase = /*#__PURE__*/ Object . freeze ( {
2023-07-09 04:05:21 -06:00
_ _proto _ _ : null ,
2023-09-21 06:49:15 -06:00
processURI : processURI$1 ,
reURI : reURI$1 ,
tests : tests$1
2023-07-09 04:05:21 -06:00
} ) ;
/ *
2023-09-21 06:49:15 -06:00
Copyright 2023 Yarmo Mackenbach
2023-07-09 04:05:21 -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 .
* /
2023-09-21 06:49:15 -06:00
const reURI = /^https:\/\/opencollective\.com\/(.*)\/?/ ;
2023-07-09 04:05:21 -06:00
/ * *
* @ function
* @ param { string } uri
* /
2023-09-21 06:49:15 -06:00
function processURI ( uri ) {
const match = uri . match ( reURI ) ;
2023-07-09 04:05:21 -06:00
return new ServiceProvider ( {
about : {
2023-09-21 06:49:15 -06:00
id : 'opencollective' ,
name : 'Open Collective' ,
homepage : 'https://opencollective.com'
2023-07-09 04:05:21 -06:00
} ,
profile : {
display : match [ 1 ] ,
uri ,
qr : null
} ,
claim : {
2023-09-21 06:49:15 -06:00
uriRegularExpression : reURI . toString ( ) ,
uriIsAmbiguous : false
2023-07-09 04:05:21 -06:00
} ,
proof : {
request : {
2023-09-21 06:49:15 -06:00
uri ,
fetcher : Fetcher . GRAPHQL ,
accessRestriction : ProofAccessRestriction . NOCORS ,
2023-07-09 04:05:21 -06:00
data : {
2023-09-21 06:49:15 -06:00
url : 'https://api.opencollective.com/graphql/v2' ,
query : ` { "query": "query { account(slug: \\ " ${ match [ 1 ] } \\ ") { longDescription } }" } `
2023-07-09 04:05:21 -06:00
}
} ,
response : {
format : ProofFormat . JSON
} ,
target : [ {
2023-09-21 06:49:15 -06:00
format : ClaimFormat . URI ,
2023-07-09 04:05:21 -06:00
encoding : EntityEncodingFormat . PLAIN ,
relation : ClaimRelation . CONTAINS ,
2023-09-21 06:49:15 -06:00
path : [ 'data' , 'account' , 'longDescription' ]
2023-07-09 04:05:21 -06:00
} ]
}
} )
}
2023-09-21 06:49:15 -06:00
const tests = [
2023-07-09 04:05:21 -06:00
{
2023-09-21 06:49:15 -06:00
uri : 'https://opencollective.com/Alice' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://opencollective.com/Alice/' ,
2023-07-09 04:05:21 -06:00
shouldMatch : true
} ,
{
2023-09-21 06:49:15 -06:00
uri : 'https://domain.org/Alice' ,
shouldMatch : false
}
] ;
var opencollective = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
processURI : processURI ,
reURI : reURI ,
tests : tests
} ) ;
/ *
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
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 _data = {
dns ,
irc ,
xmpp ,
matrix ,
telegram ,
twitter ,
reddit ,
liberapay ,
lichess ,
hackernews ,
lobsters ,
forem ,
2023-09-23 02:16:41 -06:00
forgejo ,
2023-09-21 06:49:15 -06:00
gitea ,
gitlab ,
github ,
activitypub ,
discourse ,
owncast ,
stackexchange ,
keybase ,
opencollective
} ;
const list = Object . keys ( _data ) ;
var index = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
data : _data ,
list : list
} ) ;
/ *
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
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 .
* /
/ * *
* Contains default values
* @ module defaults
* /
/ * *
* The default options used throughout the library
* @ constant { object }
* @ property { object } proxy - Options related to the proxy
* @ property { string | null } proxy . hostname - The hostname of the proxy
* @ property { string } proxy . policy - The policy that defines when to use a proxy ( { @ link module : enums ~ ProxyPolicy | here } )
* @ property { object } claims - Options related to claim verification
* @ property { object } claims . activitypub - Options related to the verification of activitypub claims
* @ property { string | null } claims . activitypub . url - The URL of the verifier account
* @ property { string | null } claims . activitypub . privateKey - The private key to sign the request
* @ property { object } claims . irc - Options related to the verification of IRC claims
* @ property { string | null } claims . irc . nick - The nick that the library uses to connect to the IRC server
* @ property { object } claims . matrix - Options related to the verification of Matrix claims
* @ property { string | null } claims . matrix . instance - The server hostname on which the library can log in
* @ property { string | null } claims . matrix . accessToken - The access token required to identify the library ( { @ link https : //www.matrix.org/docs/guides/client-server-api|Matrix docs})
* @ property { object } claims . telegram - Options related to the verification of Telegram claims
* @ property { string | null } claims . telegram . token - The Telegram API ' s token ( { @ link https : //core.telegram.org/bots/api#authorizing-your-bot|Telegram docs})
* @ property { object } claims . xmpp - Options related to the verification of XMPP claims
* @ property { string | null } claims . xmpp . service - The server hostname on which the library can log in
* @ property { string | null } claims . xmpp . username - The username used to log in
* @ property { string | null } claims . xmpp . password - The password used to log in
* /
const opts = {
proxy : {
hostname : null ,
policy : ProxyPolicy . NEVER
2023-07-09 04:05:21 -06:00
} ,
2023-09-21 06:49:15 -06:00
claims : {
activitypub : {
url : null ,
privateKey : null
} ,
irc : {
nick : null
} ,
matrix : {
instance : null ,
accessToken : null
} ,
telegram : {
token : null
} ,
xmpp : {
service : null ,
username : null ,
password : null
}
2023-07-09 04:05:21 -06:00
}
2023-09-21 06:49:15 -06:00
} ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
var defaults$3 = /*#__PURE__*/ Object . freeze ( {
2023-07-09 04:05:21 -06:00
_ _proto _ _ : null ,
2023-09-21 06:49:15 -06:00
opts : opts
2023-07-09 04:05:21 -06:00
} ) ;
/ *
2023-09-21 06:49:15 -06:00
Copyright 2021 Yarmo Mackenbach
2023-07-09 04:05:21 -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 .
* /
/ * *
2023-09-21 06:49:15 -06:00
* @ class
* @ classdesc Identity claim
* @ property { string } uri - The claim ' s URI
* @ property { string } fingerprint - The fingerprint to verify the claim against
* @ property { number } status - The current status code of the claim
* @ property { Array < object > } matches - The claim definitions matched against the URI
2023-07-09 04:05:21 -06:00
* /
2023-09-21 06:49:15 -06:00
class Claim {
/ * *
* Initialize a Claim object
* @ constructor
* @ param { string } [ uri ] - The URI of the identity claim
* @ param { string } [ fingerprint ] - The fingerprint of the OpenPGP key
* @ example
* const claim = doip . Claim ( ) ;
* const claim = doip . Claim ( 'dns:domain.tld?type=TXT' ) ;
* const claim = doip . Claim ( 'dns:domain.tld?type=TXT' , '123abc123abc' ) ;
* /
constructor ( uri , fingerprint ) {
// Verify validity of URI
if ( uri && ! validUrlExports . isUri ( uri ) ) {
throw new Error ( 'Invalid URI' )
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
// Verify validity of fingerprint
if ( fingerprint ) {
try {
// @ts-ignore
_default . default ( fingerprint ) ;
} catch ( err ) {
throw new Error ( 'Invalid fingerprint' )
}
2023-07-09 04:05:21 -06:00
}
2023-09-21 06:49:15 -06:00
/ * *
* @ type { string }
* /
this . _uri = uri || '' ;
/ * *
* @ type { string }
* /
this . _fingerprint = fingerprint || '' ;
/ * *
* @ type { number }
* /
this . _status = ClaimStatus . INIT ;
/ * *
* @ type { import ( './serviceProvider.js' ) . ServiceProvider [ ] }
* /
this . _matches = [ ] ;
2023-07-09 04:05:21 -06:00
}
2023-09-21 06:49:15 -06:00
/ * *
* @ function
* @ param { object } claimObject
* @ returns { Claim | Error }
* @ example
* doip . Claim . fromJSON ( JSON . stringify ( claim ) ) ;
* /
static fromJSON ( claimObject ) {
/** @type {Claim} */
let claim ;
let result ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
if ( typeof claimObject === 'object' && 'claimVersion' in claimObject ) {
switch ( claimObject . claimVersion ) {
case 1 :
result = importJsonClaimVersion1 ( claimObject ) ;
if ( result instanceof Error ) {
throw result
}
claim = result ;
break
case 2 :
result = importJsonClaimVersion2 ( claimObject ) ;
if ( result instanceof Error ) {
throw result
}
claim = result ;
break
default :
throw new Error ( 'Invalid claim version' )
}
}
return claim
}
get uri ( ) {
return this . _uri
}
get fingerprint ( ) {
return this . _fingerprint
}
get status ( ) {
return this . _status
}
get matches ( ) {
if ( this . _status === ClaimStatus . INIT ) {
throw new Error ( 'This claim has not yet been matched' )
}
return this . _matches
}
set uri ( uri ) {
if ( this . _status !== ClaimStatus . INIT ) {
throw new Error (
'Cannot change the URI, this claim has already been matched'
)
}
// Verify validity of URI
if ( uri . length > 0 && ! validUrlExports . isUri ( uri ) ) {
throw new Error ( 'The URI was invalid' )
}
// Remove leading and trailing spaces
uri = uri . replace ( /^\s+|\s+$/g , '' ) ;
this . _uri = uri ;
}
set fingerprint ( fingerprint ) {
if ( this . _status === ClaimStatus . VERIFIED ) {
throw new Error (
'Cannot change the fingerprint, this claim has already been verified'
)
}
this . _fingerprint = fingerprint ;
}
set status ( anything ) {
throw new Error ( "Cannot change a claim's status" )
}
set matches ( anything ) {
throw new Error ( "Cannot change a claim's matches" )
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
/ * *
* Match the claim ' s URI to candidate definitions
* @ function
* /
match ( ) {
if ( this . _status !== ClaimStatus . INIT ) {
throw new Error ( 'This claim was already matched' )
}
if ( this . _uri . length === 0 || ! validUrlExports . isUri ( this . _uri ) ) {
throw new Error ( 'This claim has no URI' )
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
this . _matches = [ ] ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
list . every ( ( name , i ) => {
const def = _data [ name ] ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
// If the candidate is invalid, continue matching
if ( ! def . reURI . test ( this . _uri ) ) {
return true
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
const candidate = def . processURI ( this . _uri ) ;
// If the candidate could not be processed, continue matching
if ( ! candidate ) {
return true
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
if ( candidate . claim . uriIsAmbiguous ) {
// Add to the possible candidates
this . _matches . push ( candidate ) ;
} else {
// Set a single candidate and stop
this . _matches = [ candidate ] ;
return false
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
// Continue matching
return true
} ) ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
this . _status = this . _matches . length === 0 ? ClaimStatus . NO _MATCHES : ClaimStatus . MATCHED ;
2023-07-09 04:05:21 -06:00
}
2023-09-21 06:49:15 -06:00
/ * *
* Verify the claim . The proof for each candidate is sequentially fetched and
* checked for the fingerprint . The verification stops when either a positive
* result was obtained , or an unambiguous claim definition was processed
* regardless of the result .
* @ async
* @ function
* @ param { object } [ opts ] - Options for proxy , fetchers
* /
async verify ( opts$1 ) {
if ( this . _status === ClaimStatus . INIT ) {
throw new Error ( 'This claim has not yet been matched' )
}
if ( this . _status >= 200 ) {
throw new Error ( 'This claim has already been verified' )
}
if ( this . _fingerprint . length === 0 ) {
throw new Error ( 'This claim has no fingerprint' )
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
// Handle options
opts$1 = mergeOptions$1 ( opts , opts$1 || { } ) ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
// If there are no matches
if ( this . _matches . length === 0 ) {
this . status = ClaimStatus . NO _MATCHES ;
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
// For each match
for ( let index = 0 ; index < this . _matches . length ; index ++ ) {
// Continue if a result was already obtained
if ( this . _status >= 200 ) { continue }
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
let claimData = this . _matches [ index ] ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
let verificationResult = null ;
let proofData = null ;
let proofFetchError ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
try {
proofData = await fetch$2 ( claimData , opts$1 ) ;
} catch ( err ) {
proofFetchError = err ;
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
if ( proofData ) {
// Run the verification process
verificationResult = await run (
proofData . result ,
claimData ,
this . _fingerprint
) ;
verificationResult . proof = {
fetcher : proofData . fetcher ,
viaProxy : proofData . viaProxy
} ;
2023-07-09 04:05:21 -06:00
2023-09-23 02:16:41 -06:00
// Validate the result
2023-09-21 06:49:15 -06:00
const def = _data [ claimData . about . id ] ;
2023-09-23 02:16:41 -06:00
if ( def . functions ? . validate && verificationResult . completed && verificationResult . result ) {
try {
( verificationResult . result = await def . functions . validate ( claimData , proofData , verificationResult , opts$1 ) ) ;
} catch ( _ ) { }
}
// Post process the data
2023-09-21 06:49:15 -06:00
if ( def . functions ? . postprocess ) {
try {
( { claimData , proofData } = await def . functions . postprocess ( claimData , proofData , opts$1 ) ) ;
} catch ( _ ) { }
}
} else {
// Consider the proof completed but with a negative result
verificationResult = verificationResult || {
result : false ,
completed : true ,
proof : { } ,
errors : [ proofFetchError ]
} ;
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
if ( this . isAmbiguous ( ) && ! verificationResult . result ) {
// Assume a wrong match and continue
continue
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
if ( verificationResult . result ) {
this . _status = verificationResult . proof . viaProxy ? ClaimStatus . VERIFIED _VIA _PROXY : ClaimStatus . VERIFIED ;
this . _matches = [ claimData ] ;
}
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
this . _status = this . _status >= 200 ? this . _status : ClaimStatus . NO _PROOF _FOUND ;
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
/ * *
* Determine the ambiguity of the claim . A claim is only unambiguous if any
* of the candidates is unambiguous . An ambiguous claim should never be
* displayed in an user interface when its result is negative .
* @ function
* @ returns { boolean }
* /
isAmbiguous ( ) {
if ( this . _status === ClaimStatus . INIT ) {
throw new Error ( 'The claim has not been matched yet' )
}
if ( this . _matches . length === 0 ) {
throw new Error ( 'The claim has no matches' )
}
return this . _matches . length > 1 || this . _matches [ 0 ] . claim . uriIsAmbiguous
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
/ * *
* Get a JSON representation of the Claim object . Useful when transferring
* data between instances / machines .
* @ function
* @ returns { object }
* /
toJSON ( ) {
let displayName = this . _uri ;
let displayUrl = null ;
let displayServiceProviderName = null ;
2023-10-03 04:05:09 -06:00
let displayServiceProviderId = null ;
2023-07-09 04:05:21 -06:00
2023-10-03 04:05:09 -06:00
if ( ! this . isAmbiguous ( ) || ( this . _status >= 200 && this . _status < 300 ) ) {
2023-09-21 06:49:15 -06:00
displayName = this . _matches [ 0 ] . profile . display ;
displayUrl = this . _matches [ 0 ] . profile . uri ;
displayServiceProviderName = this . _matches [ 0 ] . about . name ;
2023-10-03 04:05:09 -06:00
displayServiceProviderId = this . _matches [ 0 ] . about . id ;
2023-09-21 06:49:15 -06:00
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
return {
claimVersion : 2 ,
uri : this . _uri ,
proofs : [ this . _fingerprint ] ,
matches : this . _matches . map ( x => x . toJSON ( ) ) ,
status : this . _status ,
display : {
name : displayName ,
url : displayUrl ,
2023-10-03 04:05:09 -06:00
serviceProviderName : displayServiceProviderName ,
serviceProviderId : displayServiceProviderId
2023-09-21 06:49:15 -06:00
}
}
}
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
/ * *
* @ param { object } claimObject
* @ returns { Claim | Error }
* /
function importJsonClaimVersion1 ( claimObject ) {
if ( ! ( 'claimVersion' in claimObject && claimObject . claimVersion === 1 ) ) {
return new Error ( 'Invalid claim' )
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
const claim = new Claim ( ) ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
claim . _uri = claimObject . uri ;
claim . _fingerprint = claimObject . fingerprint ;
claim . _matches = claimObject . matches . map ( x => new ServiceProvider ( x ) ) ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
if ( claimObject . status === 'init' ) {
claim . _status = 100 ;
}
if ( claimObject . status === 'matched' ) {
if ( claimObject . matches . length === 0 ) {
claim . _status = 301 ;
}
claim . _status = 101 ;
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
if ( ! ( 'result' in claimObject . verification && 'errors' in claimObject . verification ) ) {
claim . _status = 400 ;
}
if ( claimObject . verification . errors . length > 0 ) {
claim . _status = 400 ;
}
if ( claimObject . verification . result && claimObject . verification . proof . viaProxy ) {
claim . _status = 201 ;
}
if ( claimObject . verification . result && ! claimObject . verification . proof . viaProxy ) {
claim . _status = 200 ;
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
return claim
}
2023-07-09 04:05:21 -06:00
/ * *
2023-09-21 06:49:15 -06:00
* @ param { object } claimObject
* @ returns { Claim | Error }
2023-07-09 04:05:21 -06:00
* /
2023-09-21 06:49:15 -06:00
function importJsonClaimVersion2 ( claimObject ) {
if ( ! ( 'claimVersion' in claimObject && claimObject . claimVersion === 2 ) ) {
return new Error ( 'Invalid claim' )
2023-07-09 04:05:21 -06:00
}
2023-09-21 06:49:15 -06:00
const claim = new Claim ( ) ;
claim . _uri = claimObject . uri ;
claim . _fingerprint = claimObject . proofs [ 0 ] ;
claim . _matches = claimObject . matches . map ( x => new ServiceProvider ( x ) ) ;
claim . _status = claimObject . status ;
return claim
}
2023-07-09 04:05:21 -06:00
/ *
2023-09-21 06:49:15 -06:00
Copyright 2023 Yarmo Mackenbach
2023-07-09 04:05:21 -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 .
* /
/ * *
2023-09-21 06:49:15 -06:00
* A persona with identity claims
2023-07-09 04:05:21 -06:00
* @ class
2023-09-21 06:49:15 -06:00
* @ constructor
* @ public
* @ example
* const claim = Claim ( 'https://alice.tld' , '123' ) ;
* const pers = Persona ( 'Alice' , 'About Alice' , [ claim ] ) ;
2023-07-09 04:05:21 -06:00
* /
2023-09-21 06:49:15 -06:00
class Persona {
2023-07-09 04:05:21 -06:00
/ * *
2023-09-21 06:49:15 -06:00
* @ param { string } name
* @ param { import ( './claim.js' ) . Claim [ ] } claims
* /
constructor ( name , claims ) {
2023-07-09 04:05:21 -06:00
/ * *
2023-09-21 06:49:15 -06:00
* Identifier of the persona
* @ type { string | null }
* @ public
2023-07-09 04:05:21 -06:00
* /
2023-09-21 06:49:15 -06:00
this . identifier = null ;
2023-07-09 04:05:21 -06:00
/ * *
2023-09-21 06:49:15 -06:00
* Name to be displayed on the profile page
2023-07-09 04:05:21 -06:00
* @ type { string }
2023-09-21 06:49:15 -06:00
* @ public
2023-07-09 04:05:21 -06:00
* /
2023-09-21 06:49:15 -06:00
this . name = name ;
2023-07-09 04:05:21 -06:00
/ * *
2023-09-21 06:49:15 -06:00
* Email address of the persona
* @ type { string | null }
* @ public
2023-07-09 04:05:21 -06:00
* /
2023-09-21 06:49:15 -06:00
this . email = null ;
2023-07-09 04:05:21 -06:00
/ * *
2023-09-21 06:49:15 -06:00
* Description to be displayed on the profile page
* @ type { string | null }
* @ public
2023-07-09 04:05:21 -06:00
* /
2023-09-21 06:49:15 -06:00
this . description = null ;
/ * *
* URL to an avatar image
* @ type { string | null }
* @ public
* /
this . avatarUrl = null ;
/ * *
* List of identity claims
* @ type { import ( './claim.js' ) . Claim [ ] }
* @ public
* /
this . claims = claims ;
/ * *
* Has the persona been revoked
* @ type { boolean }
* @ public
* /
this . isRevoked = false ;
2023-07-09 04:05:21 -06:00
}
/ * *
* @ function
2023-09-21 06:49:15 -06:00
* @ param { object } personaObject
* @ param { number } profileVersion
* @ returns { Persona | Error }
2023-07-09 04:05:21 -06:00
* @ example
2023-09-21 06:49:15 -06:00
* doip . Persona . fromJSON ( JSON . stringify ( persona ) , 2 ) ;
2023-07-09 04:05:21 -06:00
* /
2023-09-21 06:49:15 -06:00
static fromJSON ( personaObject , profileVersion ) {
/** @type {Persona} */
let persona ;
2023-07-09 04:05:21 -06:00
let result ;
2023-09-21 06:49:15 -06:00
if ( typeof personaObject === 'object' && profileVersion ) {
switch ( profileVersion ) {
2023-07-09 04:05:21 -06:00
case 2 :
2023-09-21 06:49:15 -06:00
result = importJsonPersonaVersion2 ( personaObject ) ;
2023-07-09 04:05:21 -06:00
if ( result instanceof Error ) {
throw result
}
2023-09-21 06:49:15 -06:00
persona = result ;
2023-07-09 04:05:21 -06:00
break
default :
2023-09-21 06:49:15 -06:00
throw new Error ( 'Invalid persona version' )
2023-07-09 04:05:21 -06:00
}
}
2023-09-21 06:49:15 -06:00
return persona
2023-07-09 04:05:21 -06:00
}
2023-09-21 06:49:15 -06:00
/ * *
* @ function
* @ param { string } identifier
* /
setIdentifier ( identifier ) {
this . identifier = identifier ;
2023-07-09 04:05:21 -06:00
}
2023-09-21 06:49:15 -06:00
/ * *
* @ function
* @ param { string } description
* /
setDescription ( description ) {
this . description = description ;
2023-07-09 04:05:21 -06:00
}
2023-09-21 06:49:15 -06:00
/ * *
* @ function
* @ param { string } email
* /
setEmailAddress ( email ) {
this . email = email ;
2023-07-09 04:05:21 -06:00
}
2023-09-21 06:49:15 -06:00
/ * *
* @ function
* @ param { string } avatarUrl
* /
setAvatarUrl ( avatarUrl ) {
this . avatarUrl = avatarUrl ;
2023-07-09 04:05:21 -06:00
}
2023-09-21 06:49:15 -06:00
/ * *
* @ function
* @ param { import ( './claim.js' ) . Claim } claim
* /
addClaim ( claim ) {
this . claims . push ( claim ) ;
2023-07-09 04:05:21 -06:00
}
2023-09-21 06:49:15 -06:00
/ * *
* @ function
* /
revoke ( ) {
this . isRevoked = true ;
2023-07-09 04:05:21 -06:00
}
/ * *
2023-09-21 06:49:15 -06:00
* Get a JSON representation of the Profile object
2023-07-09 04:05:21 -06:00
* @ function
2023-09-21 06:49:15 -06:00
* @ returns { object }
2023-07-09 04:05:21 -06:00
* /
2023-09-21 06:49:15 -06:00
toJSON ( ) {
return {
identifier : this . identifier ,
name : this . name ,
email : this . email ,
description : this . description ,
avatarUrl : this . avatarUrl ,
isRevoked : this . isRevoked ,
claims : this . claims . map ( x => x . toJSON ( ) )
2023-07-09 04:05:21 -06:00
}
2023-09-21 06:49:15 -06:00
}
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
/ * *
* @ param { object } personaObject
* @ returns { Persona | Error }
* /
function importJsonPersonaVersion2 ( personaObject ) {
const claims = personaObject . claims . map ( x => Claim . fromJSON ( x ) ) ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
const persona = new Persona ( personaObject . name , claims ) ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
persona . identifier = personaObject . identifier ;
persona . email = personaObject . email ;
persona . description = personaObject . description ;
persona . avatarUrl = personaObject . avatarUrl ;
persona . isRevoked = personaObject . isRevoked ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
return persona
}
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
/ *
Copyright 2023 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 .
* /
/ * *
* A profile of personas with identity claims
* @ function
* @ param { Array < import ( './persona.js' ) . Persona > } personas
* @ public
* @ example
* const claim = Claim ( 'https://alice.tld' , '123' ) ;
* const pers = Persona ( 'Alice' , 'About Alice' , [ claim ] ) ;
* const profile = Profile ( [ pers ] ) ;
* /
class Profile {
/ * *
* Create a new profile
* @ function
* @ param { import ( './enums.js' ) . ProfileType } profileType
* @ param { string } identifier
* @ param { Array < import ( './persona.js' ) . Persona > } personas
* @ public
* /
constructor ( profileType , identifier , personas ) {
/ * *
* Profile version
* @ type { number }
* @ public
* /
this . profileVersion = 2 ;
/ * *
* Profile version
* @ type { import ( './enums.js' ) . ProfileType }
* @ public
* /
this . profileType = profileType ;
/ * *
* Identifier of the profile ( fingerprint , email address , uri ... )
* @ type { string }
* @ public
* /
this . identifier = identifier ;
/ * *
* List of personas
* @ type { Array < import ( './persona.js' ) . Persona > }
* @ public
* /
this . personas = personas || [ ] ;
/ * *
* Index of primary persona ( to be displayed first or prominently )
* @ type { number }
* @ public
* /
this . primaryPersonaIndex = personas . length > 0 ? 0 : - 1 ;
/ * *
* The cryptographic key associated with the profile
* @ property { object }
* @ public
* /
this . publicKey = {
/ * *
* The type of cryptographic key
* @ type { PublicKeyType }
* @ public
* /
keyType : PublicKeyType . NONE ,
/ * *
* The fingerprint of the cryptographic key
* @ type { string | null }
* @ public
* /
fingerprint : null ,
/ * *
* The encoding of the cryptographic key
* @ type { PublicKeyEncoding }
* @ public
* /
encoding : PublicKeyEncoding . NONE ,
/ * *
* The encoded cryptographic key
* @ type { string | null }
* @ public
* /
encodedKey : null ,
/ * *
* The raw cryptographic key as object ( to be removed during toJSON ( ) )
* @ type { import ( 'openpgp' ) . PublicKey | import ( 'jose' ) . JWK | null }
* @ public
* /
key : null ,
/ * *
* Details on how to fetch the public key
* @ property { object }
* @ public
* /
fetch : {
/ * *
* The method to fetch the key
* @ type { PublicKeyFetchMethod }
* @ public
* /
method : PublicKeyFetchMethod . NONE ,
/ * *
* The query to fetch the key
* @ type { string | null }
* @ public
* /
query : null ,
/ * *
* The URL the method eventually resolved to
* @ type { string | null }
* @ public
* /
resolvedUrl : null
2023-07-09 04:05:21 -06:00
}
2023-09-21 06:49:15 -06:00
} ;
/ * *
* List of verifier URLs
* @ type { { name : string , url : string } [ ] }
* @ public
* /
this . verifiers = [ ] ;
2023-07-09 04:05:21 -06:00
}
/ * *
* @ function
2023-09-21 06:49:15 -06:00
* @ param { object } profileObject
* @ returns { Profile | Error }
* @ example
* doip . Profile . fromJSON ( JSON . stringify ( profile ) ) ;
2023-07-09 04:05:21 -06:00
* /
2023-09-21 06:49:15 -06:00
static fromJSON ( profileObject ) {
/** @type {Profile} */
let profile ;
let result ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
if ( typeof profileObject === 'object' && 'profileVersion' in profileObject ) {
switch ( profileObject . profileVersion ) {
case 2 :
result = importJsonProfileVersion2 ( profileObject ) ;
if ( result instanceof Error ) {
throw result
}
profile = result ;
break
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
default :
throw new Error ( 'Invalid profile version' )
2023-07-09 04:05:21 -06:00
}
}
2023-09-21 06:49:15 -06:00
return profile
2023-07-09 04:05:21 -06:00
}
/ * *
* @ function
2023-09-21 06:49:15 -06:00
* @ param { string } name
* @ param { string } url
2023-07-09 04:05:21 -06:00
* /
2023-09-21 06:49:15 -06:00
addVerifier ( name , url ) {
this . verifiers . push ( { name , url } ) ;
2023-07-09 04:05:21 -06:00
}
/ * *
2023-09-21 06:49:15 -06:00
* Get a JSON representation of the Profile object
2023-07-09 04:05:21 -06:00
* @ function
* @ returns { object }
* /
toJSON ( ) {
return {
2023-09-21 06:49:15 -06:00
profileVersion : this . profileVersion ,
profileType : this . profileType ,
identifier : this . identifier ,
personas : this . personas . map ( x => x . toJSON ( ) ) ,
primaryPersonaIndex : this . primaryPersonaIndex ,
publicKey : {
keyType : this . publicKey . keyType ,
fingerprint : this . publicKey . fingerprint ,
encoding : this . publicKey . encoding ,
encodedKey : this . publicKey . encodedKey ,
fetch : {
method : this . publicKey . fetch . method ,
query : this . publicKey . fetch . query ,
resolvedUrl : this . publicKey . fetch . resolvedUrl
}
} ,
verifiers : this . verifiers
2023-07-09 04:05:21 -06:00
}
}
}
/ * *
2023-09-21 06:49:15 -06:00
* @ param { object } profileObject
* @ returns { Profile | Error }
2023-07-09 04:05:21 -06:00
* /
2023-09-21 06:49:15 -06:00
function importJsonProfileVersion2 ( profileObject ) {
if ( ! ( 'profileVersion' in profileObject && profileObject . profileVersion === 2 ) ) {
return new Error ( 'Invalid profile' )
2023-07-09 04:05:21 -06:00
}
2023-09-21 06:49:15 -06:00
const personas = profileObject . personas . map ( x => Persona . fromJSON ( x , 2 ) ) ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
const profile = new Profile ( profileObject . profileType , profileObject . identifier , personas ) ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
profile . primaryPersonaIndex = profileObject . primaryPersonaIndex ;
profile . publicKey = profileObject . publicKey ;
profile . verifiers = profileObject . verifiers ;
2023-07-09 04:05:21 -06:00
2023-09-21 06:49:15 -06:00
return profile
2023-07-09 04:05:21 -06:00
}
var axios$3 = { exports : { } } ;
var bind$2 = function bind ( fn , thisArg ) {
return function wrap ( ) {
var args = new Array ( arguments . length ) ;
for ( var i = 0 ; i < args . length ; i ++ ) {
args [ i ] = arguments [ i ] ;
}
return fn . apply ( thisArg , args ) ;
} ;
} ;
var bind$1 = bind$2 ;
// utils is a library of generic helper functions non-specific to axios
var toString = Object . prototype . toString ;
/ * *
* Determine if a value is an Array
*
* @ param { Object } val The value to test
* @ returns { boolean } True if value is an Array , otherwise false
* /
function isArray ( val ) {
return Array . isArray ( val ) ;
}
/ * *
* Determine if a value is undefined
*
* @ param { Object } val The value to test
* @ returns { boolean } True if the value is undefined , otherwise false
* /
function isUndefined ( val ) {
return typeof val === 'undefined' ;
}
/ * *
* Determine if a value is a Buffer
*
* @ param { Object } val The value to test
* @ returns { boolean } True if value is a Buffer , otherwise false
* /
function isBuffer ( val ) {
return val !== null && ! isUndefined ( val ) && val . constructor !== null && ! isUndefined ( val . constructor )
&& typeof val . constructor . isBuffer === 'function' && val . constructor . isBuffer ( val ) ;
}
/ * *
* Determine if a value is an ArrayBuffer
*
* @ param { Object } val The value to test
* @ returns { boolean } True if value is an ArrayBuffer , otherwise false
* /
function isArrayBuffer ( val ) {
return toString . call ( val ) === '[object ArrayBuffer]' ;
}
/ * *
* Determine if a value is a FormData
*
* @ param { Object } val The value to test
* @ returns { boolean } True if value is an FormData , otherwise false
* /
function isFormData ( val ) {
return toString . call ( val ) === '[object FormData]' ;
}
/ * *
* Determine if a value is a view on an ArrayBuffer
*
* @ param { Object } val The value to test
* @ returns { boolean } True if value is a view on an ArrayBuffer , otherwise false
* /
function isArrayBufferView ( val ) {
var result ;
if ( ( typeof ArrayBuffer !== 'undefined' ) && ( ArrayBuffer . isView ) ) {
result = ArrayBuffer . isView ( val ) ;
} else {
result = ( val ) && ( val . buffer ) && ( isArrayBuffer ( val . buffer ) ) ;
}
return result ;
}
/ * *
* Determine if a value is a String
*
* @ param { Object } val The value to test
* @ returns { boolean } True if value is a String , otherwise false
* /
function isString ( val ) {
return typeof val === 'string' ;
}
/ * *
* Determine if a value is a Number
*
* @ param { Object } val The value to test
* @ returns { boolean } True if value is a Number , otherwise false
* /
function isNumber ( val ) {
return typeof val === 'number' ;
}
/ * *
* Determine if a value is an Object
*
* @ param { Object } val The value to test
* @ returns { boolean } True if value is an Object , otherwise false
* /
function isObject$1 ( val ) {
return val !== null && typeof val === 'object' ;
}
/ * *
* Determine if a value is a plain Object
*
* @ param { Object } val The value to test
* @ return { boolean } True if value is a plain Object , otherwise false
* /
function isPlainObject ( val ) {
if ( toString . call ( val ) !== '[object Object]' ) {
return false ;
}
var prototype = Object . getPrototypeOf ( val ) ;
return prototype === null || prototype === Object . prototype ;
}
/ * *
* Determine if a value is a Date
*
* @ param { Object } val The value to test
* @ returns { boolean } True if value is a Date , otherwise false
* /
function isDate ( val ) {
return toString . call ( val ) === '[object Date]' ;
}
/ * *
* Determine if a value is a File
*
* @ param { Object } val The value to test
* @ returns { boolean } True if value is a File , otherwise false
* /
function isFile ( val ) {
return toString . call ( val ) === '[object File]' ;
}
/ * *
* Determine if a value is a Blob
*
* @ param { Object } val The value to test
* @ returns { boolean } True if value is a Blob , otherwise false
* /
function isBlob ( val ) {
return toString . call ( val ) === '[object Blob]' ;
}
/ * *
* Determine if a value is a Function
*
* @ param { Object } val The value to test
* @ returns { boolean } True if value is a Function , otherwise false
* /
function isFunction ( val ) {
return toString . call ( val ) === '[object Function]' ;
}
/ * *
* Determine if a value is a Stream
*
* @ param { Object } val The value to test
* @ returns { boolean } True if value is a Stream , otherwise false
* /
function isStream ( val ) {
return isObject$1 ( val ) && isFunction ( val . pipe ) ;
}
/ * *
* Determine if a value is a URLSearchParams object
*
* @ param { Object } val The value to test
* @ returns { boolean } True if value is a URLSearchParams object , otherwise false
* /
function isURLSearchParams ( val ) {
return toString . call ( val ) === '[object URLSearchParams]' ;
}
/ * *
* Trim excess whitespace off the beginning and end of a string
*
* @ param { String } str The String to trim
* @ returns { String } The String freed of excess whitespace
* /
function trim ( str ) {
return str . trim ? str . trim ( ) : str . replace ( /^\s+|\s+$/g , '' ) ;
}
/ * *
* Determine if we ' re running in a standard browser environment
*
* This allows axios to run in a web worker , and react - native .
* Both environments support XMLHttpRequest , but not fully standard globals .
*
* web workers :
* typeof window - > undefined
* typeof document - > undefined
*
* react - native :
* navigator . product - > 'ReactNative'
* nativescript
* navigator . product - > 'NativeScript' or 'NS'
* /
function isStandardBrowserEnv ( ) {
if ( typeof navigator !== 'undefined' && ( navigator . product === 'ReactNative' ||
navigator . product === 'NativeScript' ||
navigator . product === 'NS' ) ) {
return false ;
}
return (
typeof window !== 'undefined' &&
typeof document !== 'undefined'
) ;
}
/ * *
* Iterate over an Array or an Object invoking a function for each item .
*
* If ` obj ` is an Array callback will be called passing
* the value , index , and complete array for each item .
*
* If 'obj' is an Object callback will be called passing
* the value , key , and complete object for each property .
*
* @ param { Object | Array } obj The object to iterate
* @ param { Function } fn The callback to invoke for each item
* /
function forEach ( obj , fn ) {
// Don't bother if no value provided
if ( obj === null || typeof obj === 'undefined' ) {
return ;
}
// Force an array if not already something iterable
if ( typeof obj !== 'object' ) {
/*eslint no-param-reassign:0*/
obj = [ obj ] ;
}
if ( isArray ( obj ) ) {
// Iterate over array values
for ( var i = 0 , l = obj . length ; i < l ; i ++ ) {
fn . call ( null , obj [ i ] , i , obj ) ;
}
} else {
// Iterate over object keys
for ( var key in obj ) {
if ( Object . prototype . hasOwnProperty . call ( obj , key ) ) {
fn . call ( null , obj [ key ] , key , obj ) ;
}
}
}
}
/ * *
* Accepts varargs expecting each argument to be an object , then
* immutably merges the properties of each object and returns result .
*
* When multiple objects contain the same key the later object in
* the arguments list will take precedence .
*
* Example :
*
* ` ` ` js
* var result = merge ( { foo : 123 } , { foo : 456 } ) ;
* console . log ( result . foo ) ; // outputs 456
* ` ` `
*
* @ param { Object } obj1 Object to merge
* @ returns { Object } Result of all merge properties
* /
function merge ( /* obj1, obj2, obj3, ... */ ) {
var result = { } ;
function assignValue ( val , key ) {
if ( isPlainObject ( result [ key ] ) && isPlainObject ( val ) ) {
result [ key ] = merge ( result [ key ] , val ) ;
} else if ( isPlainObject ( val ) ) {
result [ key ] = merge ( { } , val ) ;
} else if ( isArray ( val ) ) {
result [ key ] = val . slice ( ) ;
} else {
result [ key ] = val ;
}
}
for ( var i = 0 , l = arguments . length ; i < l ; i ++ ) {
forEach ( arguments [ i ] , assignValue ) ;
}
return result ;
}
/ * *
* Extends object a by mutably adding to it the properties of object b .
*
* @ param { Object } a The object to be extended
* @ param { Object } b The object to copy properties from
* @ param { Object } thisArg The object to bind function to
* @ return { Object } The resulting value of object a
* /
function extend ( a , b , thisArg ) {
forEach ( b , function assignValue ( val , key ) {
if ( thisArg && typeof val === 'function' ) {
a [ key ] = bind$1 ( val , thisArg ) ;
} else {
a [ key ] = val ;
}
} ) ;
return a ;
}
/ * *
* Remove byte order marker . This catches EF BB BF ( the UTF - 8 BOM )
*
* @ param { string } content with BOM
* @ return { string } content value without BOM
* /
function stripBOM ( content ) {
if ( content . charCodeAt ( 0 ) === 0xFEFF ) {
content = content . slice ( 1 ) ;
}
return content ;
}
var utils$8 = {
isArray : isArray ,
isArrayBuffer : isArrayBuffer ,
isBuffer : isBuffer ,
isFormData : isFormData ,
isArrayBufferView : isArrayBufferView ,
isString : isString ,
isNumber : isNumber ,
isObject : isObject$1 ,
isPlainObject : isPlainObject ,
isUndefined : isUndefined ,
isDate : isDate ,
isFile : isFile ,
isBlob : isBlob ,
isFunction : isFunction ,
isStream : isStream ,
isURLSearchParams : isURLSearchParams ,
isStandardBrowserEnv : isStandardBrowserEnv ,
forEach : forEach ,
merge : merge ,
extend : extend ,
trim : trim ,
stripBOM : stripBOM
} ;
var utils$7 = utils$8 ;
function encode$1 ( val ) {
return encodeURIComponent ( val ) .
replace ( /%3A/gi , ':' ) .
replace ( /%24/g , '$' ) .
replace ( /%2C/gi , ',' ) .
replace ( /%20/g , '+' ) .
replace ( /%5B/gi , '[' ) .
replace ( /%5D/gi , ']' ) ;
}
/ * *
* Build a URL by appending params to the end
*
* @ param { string } url The base of the url ( e . g . , http : //www.google.com)
* @ param { object } [ params ] The params to be appended
* @ returns { string } The formatted url
* /
var buildURL$1 = function buildURL ( url , params , paramsSerializer ) {
/*eslint no-param-reassign:0*/
if ( ! params ) {
return url ;
}
var serializedParams ;
if ( paramsSerializer ) {
serializedParams = paramsSerializer ( params ) ;
} else if ( utils$7 . isURLSearchParams ( params ) ) {
serializedParams = params . toString ( ) ;
} else {
var parts = [ ] ;
utils$7 . forEach ( params , function serialize ( val , key ) {
if ( val === null || typeof val === 'undefined' ) {
return ;
}
if ( utils$7 . isArray ( val ) ) {
key = key + '[]' ;
} else {
val = [ val ] ;
}
utils$7 . forEach ( val , function parseValue ( v ) {
if ( utils$7 . isDate ( v ) ) {
v = v . toISOString ( ) ;
} else if ( utils$7 . isObject ( v ) ) {
v = JSON . stringify ( v ) ;
}
parts . push ( encode$1 ( key ) + '=' + encode$1 ( v ) ) ;
} ) ;
} ) ;
serializedParams = parts . join ( '&' ) ;
}
if ( serializedParams ) {
var hashmarkIndex = url . indexOf ( '#' ) ;
if ( hashmarkIndex !== - 1 ) {
url = url . slice ( 0 , hashmarkIndex ) ;
}
url += ( url . indexOf ( '?' ) === - 1 ? '?' : '&' ) + serializedParams ;
}
return url ;
} ;
var utils$6 = utils$8 ;
function InterceptorManager$1 ( ) {
this . handlers = [ ] ;
}
/ * *
* Add a new interceptor to the stack
*
* @ param { Function } fulfilled The function to handle ` then ` for a ` Promise `
* @ param { Function } rejected The function to handle ` reject ` for a ` Promise `
*
* @ return { Number } An ID used to remove interceptor later
* /
InterceptorManager$1 . prototype . use = function use ( fulfilled , rejected , options ) {
this . handlers . push ( {
fulfilled : fulfilled ,
rejected : rejected ,
synchronous : options ? options . synchronous : false ,
runWhen : options ? options . runWhen : null
} ) ;
return this . handlers . length - 1 ;
} ;
/ * *
* Remove an interceptor from the stack
*
* @ param { Number } id The ID that was returned by ` use `
* /
InterceptorManager$1 . prototype . eject = function eject ( id ) {
if ( this . handlers [ id ] ) {
this . handlers [ id ] = null ;
}
} ;
/ * *
* Iterate over all the registered interceptors
*
* This method is particularly useful for skipping over any
* interceptors that may have become ` null ` calling ` eject ` .
*
* @ param { Function } fn The function to call for each interceptor
* /
InterceptorManager$1 . prototype . forEach = function forEach ( fn ) {
utils$6 . forEach ( this . handlers , function forEachHandler ( h ) {
if ( h !== null ) {
fn ( h ) ;
}
} ) ;
} ;
var InterceptorManager _1 = InterceptorManager$1 ;
var utils$5 = utils$8 ;
var normalizeHeaderName = function normalizeHeaderName ( headers , normalizedName ) {
utils$5 . forEach ( headers , function processHeader ( value , name ) {
if ( name !== normalizedName && name . toUpperCase ( ) === normalizedName . toUpperCase ( ) ) {
headers [ normalizedName ] = value ;
delete headers [ name ] ;
}
} ) ;
} ;
/ * *
* Update an Error with the specified config , error code , and response .
*
* @ param { Error } error The error to update .
* @ param { Object } config The config .
* @ param { string } [ code ] The error code ( for example , 'ECONNABORTED' ) .
* @ param { Object } [ request ] The request .
* @ param { Object } [ response ] The response .
* @ returns { Error } The error .
* /
var enhanceError = function enhanceError ( error , config , code , request , response ) {
error . config = config ;
if ( code ) {
error . code = code ;
}
error . request = request ;
error . response = response ;
error . isAxiosError = true ;
error . toJSON = function toJSON ( ) {
return {
// Standard
message : this . message ,
name : this . name ,
// Microsoft
description : this . description ,
number : this . number ,
// Mozilla
fileName : this . fileName ,
lineNumber : this . lineNumber ,
columnNumber : this . columnNumber ,
stack : this . stack ,
// Axios
config : this . config ,
code : this . code ,
status : this . response && this . response . status ? this . response . status : null
} ;
} ;
return error ;
} ;
var createError ;
var hasRequiredCreateError ;
function requireCreateError ( ) {
if ( hasRequiredCreateError ) return createError ;
hasRequiredCreateError = 1 ;
var enhanceError$1 = enhanceError ;
/ * *
* Create an Error with the specified message , config , error code , request and response .
*
* @ param { string } message The error message .
* @ param { Object } config The config .
* @ param { string } [ code ] The error code ( for example , 'ECONNABORTED' ) .
* @ param { Object } [ request ] The request .
* @ param { Object } [ response ] The response .
* @ returns { Error } The created error .
* /
createError = function createError ( message , config , code , request , response ) {
var error = new Error ( message ) ;
return enhanceError$1 ( error , config , code , request , response ) ;
} ;
return createError ;
}
var settle ;
var hasRequiredSettle ;
function requireSettle ( ) {
if ( hasRequiredSettle ) return settle ;
hasRequiredSettle = 1 ;
var createError = requireCreateError ( ) ;
/ * *
* Resolve or reject a Promise based on response status .
*
* @ param { Function } resolve A function that resolves the promise .
* @ param { Function } reject A function that rejects the promise .
* @ param { object } response The response .
* /
settle = function settle ( resolve , reject , response ) {
var validateStatus = response . config . validateStatus ;
if ( ! response . status || ! validateStatus || validateStatus ( response . status ) ) {
resolve ( response ) ;
} else {
reject ( createError (
'Request failed with status code ' + response . status ,
response . config ,
null ,
response . request ,
response
) ) ;
}
} ;
return settle ;
}
var cookies ;
var hasRequiredCookies ;
function requireCookies ( ) {
if ( hasRequiredCookies ) return cookies ;
hasRequiredCookies = 1 ;
var utils = utils$8 ;
cookies = (
utils . isStandardBrowserEnv ( ) ?
// Standard browser envs support document.cookie
( function standardBrowserEnv ( ) {
return {
write : function write ( name , value , expires , path , domain , secure ) {
var cookie = [ ] ;
cookie . push ( name + '=' + encodeURIComponent ( value ) ) ;
if ( utils . isNumber ( expires ) ) {
cookie . push ( 'expires=' + new Date ( expires ) . toGMTString ( ) ) ;
}
if ( utils . isString ( path ) ) {
cookie . push ( 'path=' + path ) ;
}
if ( utils . isString ( domain ) ) {
cookie . push ( 'domain=' + domain ) ;
}
if ( secure === true ) {
cookie . push ( 'secure' ) ;
}
document . cookie = cookie . join ( '; ' ) ;
} ,
read : function read ( name ) {
var match = document . cookie . match ( new RegExp ( '(^|;\\s*)(' + name + ')=([^;]*)' ) ) ;
return ( match ? decodeURIComponent ( match [ 3 ] ) : null ) ;
} ,
remove : function remove ( name ) {
this . write ( name , '' , Date . now ( ) - 86400000 ) ;
}
} ;
} ) ( ) :
// Non standard browser env (web workers, react-native) lack needed support.
( function nonStandardBrowserEnv ( ) {
return {
write : function write ( ) { } ,
read : function read ( ) { return null ; } ,
remove : function remove ( ) { }
} ;
} ) ( )
) ;
return cookies ;
}
var isAbsoluteURL ;
var hasRequiredIsAbsoluteURL ;
function requireIsAbsoluteURL ( ) {
if ( hasRequiredIsAbsoluteURL ) return isAbsoluteURL ;
hasRequiredIsAbsoluteURL = 1 ;
/ * *
* Determines whether the specified URL is absolute
*
* @ param { string } url The URL to test
* @ returns { boolean } True if the specified URL is absolute , otherwise false
* /
isAbsoluteURL = function isAbsoluteURL ( url ) {
// A URL is considered absolute if it begins with "<scheme>://" or "//" (protocol-relative URL).
// RFC 3986 defines scheme name as a sequence of characters beginning with a letter and followed
// by any combination of letters, digits, plus, period, or hyphen.
return /^([a-z][a-z\d+\-.]*:)?\/\//i . test ( url ) ;
} ;
return isAbsoluteURL ;
}
var combineURLs ;
var hasRequiredCombineURLs ;
function requireCombineURLs ( ) {
if ( hasRequiredCombineURLs ) return combineURLs ;
hasRequiredCombineURLs = 1 ;
/ * *
* Creates a new URL by combining the specified URLs
*
* @ param { string } baseURL The base URL
* @ param { string } relativeURL The relative URL
* @ returns { string } The combined URL
* /
combineURLs = function combineURLs ( baseURL , relativeURL ) {
return relativeURL
? baseURL . replace ( /\/+$/ , '' ) + '/' + relativeURL . replace ( /^\/+/ , '' )
: baseURL ;
} ;
return combineURLs ;
}
var buildFullPath ;
var hasRequiredBuildFullPath ;
function requireBuildFullPath ( ) {
if ( hasRequiredBuildFullPath ) return buildFullPath ;
hasRequiredBuildFullPath = 1 ;
var isAbsoluteURL = requireIsAbsoluteURL ( ) ;
var combineURLs = requireCombineURLs ( ) ;
/ * *
* Creates a new URL by combining the baseURL with the requestedURL ,
* only when the requestedURL is not already an absolute URL .
* If the requestURL is absolute , this function returns the requestedURL untouched .
*
* @ param { string } baseURL The base URL
* @ param { string } requestedURL Absolute or relative URL to combine
* @ returns { string } The combined full path
* /
buildFullPath = function buildFullPath ( baseURL , requestedURL ) {
if ( baseURL && ! isAbsoluteURL ( requestedURL ) ) {
return combineURLs ( baseURL , requestedURL ) ;
}
return requestedURL ;
} ;
return buildFullPath ;
}
var parseHeaders ;
var hasRequiredParseHeaders ;
function requireParseHeaders ( ) {
if ( hasRequiredParseHeaders ) return parseHeaders ;
hasRequiredParseHeaders = 1 ;
var utils = utils$8 ;
// Headers whose duplicates are ignored by node
// c.f. https://nodejs.org/api/http.html#http_message_headers
var ignoreDuplicateOf = [
'age' , 'authorization' , 'content-length' , 'content-type' , 'etag' ,
'expires' , 'from' , 'host' , 'if-modified-since' , 'if-unmodified-since' ,
'last-modified' , 'location' , 'max-forwards' , 'proxy-authorization' ,
'referer' , 'retry-after' , 'user-agent'
] ;
/ * *
* Parse headers into an object
*
* ` ` `
* Date : Wed , 27 Aug 2014 08 : 58 : 49 GMT
* Content - Type : application / json
* Connection : keep - alive
* Transfer - Encoding : chunked
* ` ` `
*
* @ param { String } headers Headers needing to be parsed
* @ returns { Object } Headers parsed into an object
* /
parseHeaders = function parseHeaders ( headers ) {
var parsed = { } ;
var key ;
var val ;
var i ;
if ( ! headers ) { return parsed ; }
utils . forEach ( headers . split ( '\n' ) , function parser ( line ) {
i = line . indexOf ( ':' ) ;
key = utils . trim ( line . substr ( 0 , i ) ) . toLowerCase ( ) ;
val = utils . trim ( line . substr ( i + 1 ) ) ;
if ( key ) {
if ( parsed [ key ] && ignoreDuplicateOf . indexOf ( key ) >= 0 ) {
return ;
}
if ( key === 'set-cookie' ) {
parsed [ key ] = ( parsed [ key ] ? parsed [ key ] : [ ] ) . concat ( [ val ] ) ;
} else {
parsed [ key ] = parsed [ key ] ? parsed [ key ] + ', ' + val : val ;
}
}
} ) ;
return parsed ;
} ;
return parseHeaders ;
}
var isURLSameOrigin ;
var hasRequiredIsURLSameOrigin ;
function requireIsURLSameOrigin ( ) {
if ( hasRequiredIsURLSameOrigin ) return isURLSameOrigin ;
hasRequiredIsURLSameOrigin = 1 ;
var utils = utils$8 ;
isURLSameOrigin = (
utils . isStandardBrowserEnv ( ) ?
// Standard browser envs have full support of the APIs needed to test
// whether the request URL is of the same origin as current location.
( function standardBrowserEnv ( ) {
var msie = /(msie|trident)/i . test ( navigator . userAgent ) ;
var urlParsingNode = document . createElement ( 'a' ) ;
var originURL ;
/ * *
* Parse a URL to discover it ' s components
*
* @ param { String } url The URL to be parsed
* @ returns { Object }
* /
function resolveURL ( url ) {
var href = url ;
if ( msie ) {
// IE needs attribute set twice to normalize properties
urlParsingNode . setAttribute ( 'href' , href ) ;
href = urlParsingNode . href ;
}
urlParsingNode . setAttribute ( 'href' , href ) ;
// urlParsingNode provides the UrlUtils interface - http://url.spec.whatwg.org/#urlutils
return {
href : urlParsingNode . href ,
protocol : urlParsingNode . protocol ? urlParsingNode . protocol . replace ( /:$/ , '' ) : '' ,
host : urlParsingNode . host ,
search : urlParsingNode . search ? urlParsingNode . search . replace ( /^\?/ , '' ) : '' ,
hash : urlParsingNode . hash ? urlParsingNode . hash . replace ( /^#/ , '' ) : '' ,
hostname : urlParsingNode . hostname ,
port : urlParsingNode . port ,
pathname : ( urlParsingNode . pathname . charAt ( 0 ) === '/' ) ?
urlParsingNode . pathname :
'/' + urlParsingNode . pathname
} ;
}
originURL = resolveURL ( window . location . href ) ;
/ * *
* Determine if a URL shares the same origin as the current location
*
* @ param { String } requestURL The URL to test
* @ returns { boolean } True if URL shares the same origin , otherwise false
* /
return function isURLSameOrigin ( requestURL ) {
var parsed = ( utils . isString ( requestURL ) ) ? resolveURL ( requestURL ) : requestURL ;
return ( parsed . protocol === originURL . protocol &&
parsed . host === originURL . host ) ;
} ;
} ) ( ) :
// Non standard browser envs (web workers, react-native) lack needed support.
( function nonStandardBrowserEnv ( ) {
return function isURLSameOrigin ( ) {
return true ;
} ;
} ) ( )
) ;
return isURLSameOrigin ;
}
var Cancel _1 ;
var hasRequiredCancel ;
function requireCancel ( ) {
if ( hasRequiredCancel ) return Cancel _1 ;
hasRequiredCancel = 1 ;
/ * *
* A ` Cancel ` is an object that is thrown when an operation is canceled .
*
* @ class
* @ param { string = } message The message .
* /
function Cancel ( message ) {
this . message = message ;
}
Cancel . prototype . toString = function toString ( ) {
return 'Cancel' + ( this . message ? ': ' + this . message : '' ) ;
} ;
Cancel . prototype . _ _CANCEL _ _ = true ;
Cancel _1 = Cancel ;
return Cancel _1 ;
}
var xhr ;
var hasRequiredXhr ;
function requireXhr ( ) {
if ( hasRequiredXhr ) return xhr ;
hasRequiredXhr = 1 ;
var utils = utils$8 ;
var settle = requireSettle ( ) ;
var cookies = requireCookies ( ) ;
var buildURL = buildURL$1 ;
var buildFullPath = requireBuildFullPath ( ) ;
var parseHeaders = requireParseHeaders ( ) ;
var isURLSameOrigin = requireIsURLSameOrigin ( ) ;
var createError = requireCreateError ( ) ;
var defaults = requireDefaults ( ) ;
var Cancel = requireCancel ( ) ;
xhr = function xhrAdapter ( config ) {
return new Promise ( function dispatchXhrRequest ( resolve , reject ) {
var requestData = config . data ;
var requestHeaders = config . headers ;
var responseType = config . responseType ;
var onCanceled ;
function done ( ) {
if ( config . cancelToken ) {
config . cancelToken . unsubscribe ( onCanceled ) ;
}
if ( config . signal ) {
config . signal . removeEventListener ( 'abort' , onCanceled ) ;
}
}
if ( utils . isFormData ( requestData ) ) {
delete requestHeaders [ 'Content-Type' ] ; // Let the browser set it
}
var request = new XMLHttpRequest ( ) ;
// HTTP basic authentication
if ( config . auth ) {
var username = config . auth . username || '' ;
var password = config . auth . password ? unescape ( encodeURIComponent ( config . auth . password ) ) : '' ;
requestHeaders . Authorization = 'Basic ' + btoa ( username + ':' + password ) ;
}
var fullPath = buildFullPath ( config . baseURL , config . url ) ;
request . open ( config . method . toUpperCase ( ) , buildURL ( fullPath , config . params , config . paramsSerializer ) , true ) ;
// Set the request timeout in MS
request . timeout = config . timeout ;
function onloadend ( ) {
if ( ! request ) {
return ;
}
// Prepare the response
var responseHeaders = 'getAllResponseHeaders' in request ? parseHeaders ( request . getAllResponseHeaders ( ) ) : null ;
var responseData = ! responseType || responseType === 'text' || responseType === 'json' ?
request . responseText : request . response ;
var response = {
data : responseData ,
status : request . status ,
statusText : request . statusText ,
headers : responseHeaders ,
config : config ,
request : request
} ;
settle ( function _resolve ( value ) {
resolve ( value ) ;
done ( ) ;
} , function _reject ( err ) {
reject ( err ) ;
done ( ) ;
} , response ) ;
// Clean up request
request = null ;
}
if ( 'onloadend' in request ) {
// Use onloadend if available
request . onloadend = onloadend ;
} else {
// Listen for ready state to emulate onloadend
request . onreadystatechange = function handleLoad ( ) {
if ( ! request || request . readyState !== 4 ) {
return ;
}
// The request errored out and we didn't get a response, this will be
// handled by onerror instead
// With one exception: request that using file: protocol, most browsers
// will return status as 0 even though it's a successful request
if ( request . status === 0 && ! ( request . responseURL && request . responseURL . indexOf ( 'file:' ) === 0 ) ) {
return ;
}
// readystate handler is calling before onerror or ontimeout handlers,
// so we should call onloadend on the next 'tick'
setTimeout ( onloadend ) ;
} ;
}
// Handle browser request cancellation (as opposed to a manual cancellation)
request . onabort = function handleAbort ( ) {
if ( ! request ) {
return ;
}
reject ( createError ( 'Request aborted' , config , 'ECONNABORTED' , request ) ) ;
// Clean up request
request = null ;
} ;
// Handle low level network errors
request . onerror = function handleError ( ) {
// Real errors are hidden from us by the browser
// onerror should only fire if it's a network error
reject ( createError ( 'Network Error' , config , null , request ) ) ;
// Clean up request
request = null ;
} ;
// Handle timeout
request . ontimeout = function handleTimeout ( ) {
var timeoutErrorMessage = config . timeout ? 'timeout of ' + config . timeout + 'ms exceeded' : 'timeout exceeded' ;
var transitional = config . transitional || defaults . transitional ;
if ( config . timeoutErrorMessage ) {
timeoutErrorMessage = config . timeoutErrorMessage ;
}
reject ( createError (
timeoutErrorMessage ,
config ,
transitional . clarifyTimeoutError ? 'ETIMEDOUT' : 'ECONNABORTED' ,
request ) ) ;
// Clean up request
request = null ;
} ;
// Add xsrf header
// This is only done if running in a standard browser environment.
// Specifically not if we're in a web worker, or react-native.
if ( utils . isStandardBrowserEnv ( ) ) {
// Add xsrf header
var xsrfValue = ( config . withCredentials || isURLSameOrigin ( fullPath ) ) && config . xsrfCookieName ?
cookies . read ( config . xsrfCookieName ) :
undefined ;
if ( xsrfValue ) {
requestHeaders [ config . xsrfHeaderName ] = xsrfValue ;
}
}
// Add headers to the request
if ( 'setRequestHeader' in request ) {
utils . forEach ( requestHeaders , function setRequestHeader ( val , key ) {
if ( typeof requestData === 'undefined' && key . toLowerCase ( ) === 'content-type' ) {
// Remove Content-Type if data is undefined
delete requestHeaders [ key ] ;
} else {
// Otherwise add header to the request
request . setRequestHeader ( key , val ) ;
}
} ) ;
}
// Add withCredentials to request if needed
if ( ! utils . isUndefined ( config . withCredentials ) ) {
request . withCredentials = ! ! config . withCredentials ;
}
// Add responseType to request if needed
if ( responseType && responseType !== 'json' ) {
request . responseType = config . responseType ;
}
// Handle progress if needed
if ( typeof config . onDownloadProgress === 'function' ) {
request . addEventListener ( 'progress' , config . onDownloadProgress ) ;
}
// Not all browsers support upload events
if ( typeof config . onUploadProgress === 'function' && request . upload ) {
request . upload . addEventListener ( 'progress' , config . onUploadProgress ) ;
}
if ( config . cancelToken || config . signal ) {
// Handle cancellation
// eslint-disable-next-line func-names
onCanceled = function ( cancel ) {
if ( ! request ) {
return ;
}
reject ( ! cancel || ( cancel && cancel . type ) ? new Cancel ( 'canceled' ) : cancel ) ;
request . abort ( ) ;
request = null ;
} ;
config . cancelToken && config . cancelToken . subscribe ( onCanceled ) ;
if ( config . signal ) {
config . signal . aborted ? onCanceled ( ) : config . signal . addEventListener ( 'abort' , onCanceled ) ;
}
}
if ( ! requestData ) {
requestData = null ;
}
// Send the request
request . send ( requestData ) ;
} ) ;
} ;
return xhr ;
}
var defaults _1 ;
var hasRequiredDefaults ;
function requireDefaults ( ) {
if ( hasRequiredDefaults ) return defaults _1 ;
hasRequiredDefaults = 1 ;
var utils = utils$8 ;
var normalizeHeaderName$1 = normalizeHeaderName ;
var enhanceError$1 = enhanceError ;
var DEFAULT _CONTENT _TYPE = {
'Content-Type' : 'application/x-www-form-urlencoded'
} ;
function setContentTypeIfUnset ( headers , value ) {
if ( ! utils . isUndefined ( headers ) && utils . isUndefined ( headers [ 'Content-Type' ] ) ) {
headers [ 'Content-Type' ] = value ;
}
}
function getDefaultAdapter ( ) {
var adapter ;
if ( typeof XMLHttpRequest !== 'undefined' ) {
// For browsers use XHR adapter
adapter = requireXhr ( ) ;
} else if ( typeof browser$1 !== 'undefined' && Object . prototype . toString . call ( browser$1 ) === '[object process]' ) {
// For node use HTTP adapter
adapter = requireXhr ( ) ;
}
return adapter ;
}
function stringifySafely ( rawValue , parser , encoder ) {
if ( utils . isString ( rawValue ) ) {
try {
( parser || JSON . parse ) ( rawValue ) ;
return utils . trim ( rawValue ) ;
} catch ( e ) {
if ( e . name !== 'SyntaxError' ) {
throw e ;
}
}
}
return ( encoder || JSON . stringify ) ( rawValue ) ;
}
var defaults = {
transitional : {
silentJSONParsing : true ,
forcedJSONParsing : true ,
clarifyTimeoutError : false
} ,
adapter : getDefaultAdapter ( ) ,
transformRequest : [ function transformRequest ( data , headers ) {
normalizeHeaderName$1 ( headers , 'Accept' ) ;
normalizeHeaderName$1 ( headers , 'Content-Type' ) ;
if ( utils . isFormData ( data ) ||
utils . isArrayBuffer ( data ) ||
utils . isBuffer ( data ) ||
utils . isStream ( data ) ||
utils . isFile ( data ) ||
utils . isBlob ( data )
) {
return data ;
}
if ( utils . isArrayBufferView ( data ) ) {
return data . buffer ;
}
if ( utils . isURLSearchParams ( data ) ) {
setContentTypeIfUnset ( headers , 'application/x-www-form-urlencoded;charset=utf-8' ) ;
return data . toString ( ) ;
}
if ( utils . isObject ( data ) || ( headers && headers [ 'Content-Type' ] === 'application/json' ) ) {
setContentTypeIfUnset ( headers , 'application/json' ) ;
return stringifySafely ( data ) ;
}
return data ;
} ] ,
transformResponse : [ function transformResponse ( data ) {
var transitional = this . transitional || defaults . transitional ;
var silentJSONParsing = transitional && transitional . silentJSONParsing ;
var forcedJSONParsing = transitional && transitional . forcedJSONParsing ;
var strictJSONParsing = ! silentJSONParsing && this . responseType === 'json' ;
if ( strictJSONParsing || ( forcedJSONParsing && utils . isString ( data ) && data . length ) ) {
try {
return JSON . parse ( data ) ;
} catch ( e ) {
if ( strictJSONParsing ) {
if ( e . name === 'SyntaxError' ) {
throw enhanceError$1 ( e , this , 'E_JSON_PARSE' ) ;
}
throw e ;
}
}
}
return data ;
} ] ,
/ * *
* A timeout in milliseconds to abort a request . If set to 0 ( default ) a
* timeout is not created .
* /
timeout : 0 ,
xsrfCookieName : 'XSRF-TOKEN' ,
xsrfHeaderName : 'X-XSRF-TOKEN' ,
maxContentLength : - 1 ,
maxBodyLength : - 1 ,
validateStatus : function validateStatus ( status ) {
return status >= 200 && status < 300 ;
} ,
headers : {
common : {
'Accept' : 'application/json, text/plain, */*'
}
}
} ;
utils . forEach ( [ 'delete' , 'get' , 'head' ] , function forEachMethodNoData ( method ) {
defaults . headers [ method ] = { } ;
} ) ;
utils . forEach ( [ 'post' , 'put' , 'patch' ] , function forEachMethodWithData ( method ) {
defaults . headers [ method ] = utils . merge ( DEFAULT _CONTENT _TYPE ) ;
} ) ;
defaults _1 = defaults ;
return defaults _1 ;
}
var utils$4 = utils$8 ;
var defaults$2 = requireDefaults ( ) ;
/ * *
* Transform the data for a request or a response
*
* @ param { Object | String } data The data to be transformed
* @ param { Array } headers The headers for the request or response
* @ param { Array | Function } fns A single function or Array of functions
* @ returns { * } The resulting transformed data
* /
var transformData$1 = function transformData ( data , headers , fns ) {
var context = this || defaults$2 ;
/*eslint no-param-reassign:0*/
utils$4 . forEach ( fns , function transform ( fn ) {
data = fn . call ( context , data , headers ) ;
} ) ;
return data ;
} ;
var isCancel$1 ;
var hasRequiredIsCancel ;
function requireIsCancel ( ) {
if ( hasRequiredIsCancel ) return isCancel$1 ;
hasRequiredIsCancel = 1 ;
isCancel$1 = function isCancel ( value ) {
return ! ! ( value && value . _ _CANCEL _ _ ) ;
} ;
return isCancel$1 ;
}
var utils$3 = utils$8 ;
var transformData = transformData$1 ;
var isCancel = requireIsCancel ( ) ;
var defaults$1 = requireDefaults ( ) ;
var Cancel = requireCancel ( ) ;
/ * *
* Throws a ` Cancel ` if cancellation has been requested .
* /
function throwIfCancellationRequested ( config ) {
if ( config . cancelToken ) {
config . cancelToken . throwIfRequested ( ) ;
}
if ( config . signal && config . signal . aborted ) {
throw new Cancel ( 'canceled' ) ;
}
}
/ * *
* Dispatch a request to the server using the configured adapter .
*
* @ param { object } config The config that is to be used for the request
* @ returns { Promise } The Promise to be fulfilled
* /
var dispatchRequest$1 = function dispatchRequest ( config ) {
throwIfCancellationRequested ( config ) ;
// Ensure headers exist
config . headers = config . headers || { } ;
// Transform request data
config . data = transformData . call (
config ,
config . data ,
config . headers ,
config . transformRequest
) ;
// Flatten headers
config . headers = utils$3 . merge (
config . headers . common || { } ,
config . headers [ config . method ] || { } ,
config . headers
) ;
utils$3 . forEach (
[ 'delete' , 'get' , 'head' , 'post' , 'put' , 'patch' , 'common' ] ,
function cleanHeaderConfig ( method ) {
delete config . headers [ method ] ;
}
) ;
var adapter = config . adapter || defaults$1 . adapter ;
return adapter ( config ) . then ( function onAdapterResolution ( response ) {
throwIfCancellationRequested ( config ) ;
// Transform response data
response . data = transformData . call (
config ,
response . data ,
response . headers ,
config . transformResponse
) ;
return response ;
} , function onAdapterRejection ( reason ) {
if ( ! isCancel ( reason ) ) {
throwIfCancellationRequested ( config ) ;
// Transform response data
if ( reason && reason . response ) {
reason . response . data = transformData . call (
config ,
reason . response . data ,
reason . response . headers ,
config . transformResponse
) ;
}
}
return Promise . reject ( reason ) ;
} ) ;
} ;
var utils$2 = utils$8 ;
/ * *
* Config - specific merge - function which creates a new config - object
* by merging two configuration objects together .
*
* @ param { Object } config1
* @ param { Object } config2
* @ returns { Object } New object resulting from merging config2 to config1
* /
var mergeConfig$2 = function mergeConfig ( config1 , config2 ) {
// eslint-disable-next-line no-param-reassign
config2 = config2 || { } ;
var config = { } ;
function getMergedValue ( target , source ) {
if ( utils$2 . isPlainObject ( target ) && utils$2 . isPlainObject ( source ) ) {
return utils$2 . merge ( target , source ) ;
} else if ( utils$2 . isPlainObject ( source ) ) {
return utils$2 . merge ( { } , source ) ;
} else if ( utils$2 . isArray ( source ) ) {
return source . slice ( ) ;
}
return source ;
}
// eslint-disable-next-line consistent-return
function mergeDeepProperties ( prop ) {
if ( ! utils$2 . isUndefined ( config2 [ prop ] ) ) {
return getMergedValue ( config1 [ prop ] , config2 [ prop ] ) ;
} else if ( ! utils$2 . isUndefined ( config1 [ prop ] ) ) {
return getMergedValue ( undefined , config1 [ prop ] ) ;
}
}
// eslint-disable-next-line consistent-return
function valueFromConfig2 ( prop ) {
if ( ! utils$2 . isUndefined ( config2 [ prop ] ) ) {
return getMergedValue ( undefined , config2 [ prop ] ) ;
}
}
// eslint-disable-next-line consistent-return
function defaultToConfig2 ( prop ) {
if ( ! utils$2 . isUndefined ( config2 [ prop ] ) ) {
return getMergedValue ( undefined , config2 [ prop ] ) ;
} else if ( ! utils$2 . isUndefined ( config1 [ prop ] ) ) {
return getMergedValue ( undefined , config1 [ prop ] ) ;
}
}
// eslint-disable-next-line consistent-return
function mergeDirectKeys ( prop ) {
if ( prop in config2 ) {
return getMergedValue ( config1 [ prop ] , config2 [ prop ] ) ;
} else if ( prop in config1 ) {
return getMergedValue ( undefined , config1 [ prop ] ) ;
}
}
var mergeMap = {
'url' : valueFromConfig2 ,
'method' : valueFromConfig2 ,
'data' : valueFromConfig2 ,
'baseURL' : defaultToConfig2 ,
'transformRequest' : defaultToConfig2 ,
'transformResponse' : defaultToConfig2 ,
'paramsSerializer' : defaultToConfig2 ,
'timeout' : defaultToConfig2 ,
'timeoutMessage' : defaultToConfig2 ,
'withCredentials' : defaultToConfig2 ,
'adapter' : defaultToConfig2 ,
'responseType' : defaultToConfig2 ,
'xsrfCookieName' : defaultToConfig2 ,
'xsrfHeaderName' : defaultToConfig2 ,
'onUploadProgress' : defaultToConfig2 ,
'onDownloadProgress' : defaultToConfig2 ,
'decompress' : defaultToConfig2 ,
'maxContentLength' : defaultToConfig2 ,
'maxBodyLength' : defaultToConfig2 ,
'transport' : defaultToConfig2 ,
'httpAgent' : defaultToConfig2 ,
'httpsAgent' : defaultToConfig2 ,
'cancelToken' : defaultToConfig2 ,
'socketPath' : defaultToConfig2 ,
'responseEncoding' : defaultToConfig2 ,
'validateStatus' : mergeDirectKeys
} ;
utils$2 . forEach ( Object . keys ( config1 ) . concat ( Object . keys ( config2 ) ) , function computeConfigValue ( prop ) {
var merge = mergeMap [ prop ] || mergeDeepProperties ;
var configValue = merge ( prop ) ;
( utils$2 . isUndefined ( configValue ) && merge !== mergeDirectKeys ) || ( config [ prop ] = configValue ) ;
} ) ;
return config ;
} ;
var data ;
var hasRequiredData ;
function requireData ( ) {
if ( hasRequiredData ) return data ;
hasRequiredData = 1 ;
data = {
"version" : "0.25.0"
} ;
return data ;
}
var VERSION = requireData ( ) . version ;
var validators$1 = { } ;
// eslint-disable-next-line func-names
[ 'object' , 'boolean' , 'number' , 'function' , 'string' , 'symbol' ] . forEach ( function ( type , i ) {
validators$1 [ type ] = function validator ( thing ) {
return typeof thing === type || 'a' + ( i < 1 ? 'n ' : ' ' ) + type ;
} ;
} ) ;
var deprecatedWarnings = { } ;
/ * *
* Transitional option validator
* @ param { function | boolean ? } validator - set to false if the transitional option has been removed
* @ param { string ? } version - deprecated version / removed since version
* @ param { string ? } message - some message with additional info
* @ returns { function }
* /
validators$1 . transitional = function transitional ( validator , version , message ) {
function formatMessage ( opt , desc ) {
return '[Axios v' + VERSION + '] Transitional option \'' + opt + '\'' + desc + ( message ? '. ' + message : '' ) ;
}
// eslint-disable-next-line func-names
return function ( value , opt , opts ) {
if ( validator === false ) {
throw new Error ( formatMessage ( opt , ' has been removed' + ( version ? ' in ' + version : '' ) ) ) ;
}
if ( version && ! deprecatedWarnings [ opt ] ) {
deprecatedWarnings [ opt ] = true ;
// eslint-disable-next-line no-console
console . warn (
formatMessage (
opt ,
' has been deprecated since v' + version + ' and will be removed in the near future'
)
) ;
}
return validator ? validator ( value , opt , opts ) : true ;
} ;
} ;
/ * *
* Assert object ' s properties type
* @ param { object } options
* @ param { object } schema
* @ param { boolean ? } allowUnknown
* /
function assertOptions ( options , schema , allowUnknown ) {
if ( typeof options !== 'object' ) {
throw new TypeError ( 'options must be an object' ) ;
}
var keys = Object . keys ( options ) ;
var i = keys . length ;
while ( i -- > 0 ) {
var opt = keys [ i ] ;
var validator = schema [ opt ] ;
if ( validator ) {
var value = options [ opt ] ;
var result = value === undefined || validator ( value , opt , options ) ;
if ( result !== true ) {
throw new TypeError ( 'option ' + opt + ' must be ' + result ) ;
}
continue ;
}
if ( allowUnknown !== true ) {
throw Error ( 'Unknown option ' + opt ) ;
}
}
}
var validator$1 = {
assertOptions : assertOptions ,
validators : validators$1
} ;
var utils$1 = utils$8 ;
var buildURL = buildURL$1 ;
var InterceptorManager = InterceptorManager _1 ;
var dispatchRequest = dispatchRequest$1 ;
var mergeConfig$1 = mergeConfig$2 ;
var validator = validator$1 ;
var validators = validator . validators ;
/ * *
* Create a new instance of Axios
*
* @ param { Object } instanceConfig The default config for the instance
* /
function Axios$1 ( instanceConfig ) {
this . defaults = instanceConfig ;
this . interceptors = {
request : new InterceptorManager ( ) ,
response : new InterceptorManager ( )
} ;
}
/ * *
* Dispatch a request
*
* @ param { Object } config The config specific for this request ( merged with this . defaults )
* /
Axios$1 . prototype . request = function request ( configOrUrl , config ) {
/*eslint no-param-reassign:0*/
// Allow for axios('example/url'[, config]) a la fetch API
if ( typeof configOrUrl === 'string' ) {
config = config || { } ;
config . url = configOrUrl ;
} else {
config = configOrUrl || { } ;
}
if ( ! config . url ) {
throw new Error ( 'Provided config url is not valid' ) ;
}
config = mergeConfig$1 ( this . defaults , config ) ;
// Set config.method
if ( config . method ) {
config . method = config . method . toLowerCase ( ) ;
} else if ( this . defaults . method ) {
config . method = this . defaults . method . toLowerCase ( ) ;
} else {
config . method = 'get' ;
}
var transitional = config . transitional ;
if ( transitional !== undefined ) {
validator . assertOptions ( transitional , {
silentJSONParsing : validators . transitional ( validators . boolean ) ,
forcedJSONParsing : validators . transitional ( validators . boolean ) ,
clarifyTimeoutError : validators . transitional ( validators . boolean )
} , false ) ;
}
// filter out skipped interceptors
var requestInterceptorChain = [ ] ;
var synchronousRequestInterceptors = true ;
this . interceptors . request . forEach ( function unshiftRequestInterceptors ( interceptor ) {
if ( typeof interceptor . runWhen === 'function' && interceptor . runWhen ( config ) === false ) {
return ;
}
synchronousRequestInterceptors = synchronousRequestInterceptors && interceptor . synchronous ;
requestInterceptorChain . unshift ( interceptor . fulfilled , interceptor . rejected ) ;
} ) ;
var responseInterceptorChain = [ ] ;
this . interceptors . response . forEach ( function pushResponseInterceptors ( interceptor ) {
responseInterceptorChain . push ( interceptor . fulfilled , interceptor . rejected ) ;
} ) ;
var promise ;
if ( ! synchronousRequestInterceptors ) {
var chain = [ dispatchRequest , undefined ] ;
Array . prototype . unshift . apply ( chain , requestInterceptorChain ) ;
chain = chain . concat ( responseInterceptorChain ) ;
promise = Promise . resolve ( config ) ;
while ( chain . length ) {
promise = promise . then ( chain . shift ( ) , chain . shift ( ) ) ;
}
return promise ;
}
var newConfig = config ;
while ( requestInterceptorChain . length ) {
var onFulfilled = requestInterceptorChain . shift ( ) ;
var onRejected = requestInterceptorChain . shift ( ) ;
try {
newConfig = onFulfilled ( newConfig ) ;
} catch ( error ) {
onRejected ( error ) ;
break ;
}
}
try {
promise = dispatchRequest ( newConfig ) ;
} catch ( error ) {
return Promise . reject ( error ) ;
}
while ( responseInterceptorChain . length ) {
promise = promise . then ( responseInterceptorChain . shift ( ) , responseInterceptorChain . shift ( ) ) ;
}
return promise ;
} ;
Axios$1 . prototype . getUri = function getUri ( config ) {
if ( ! config . url ) {
throw new Error ( 'Provided config url is not valid' ) ;
}
config = mergeConfig$1 ( this . defaults , config ) ;
return buildURL ( config . url , config . params , config . paramsSerializer ) . replace ( /^\?/ , '' ) ;
} ;
// Provide aliases for supported request methods
utils$1 . forEach ( [ 'delete' , 'get' , 'head' , 'options' ] , function forEachMethodNoData ( method ) {
/*eslint func-names:0*/
Axios$1 . prototype [ method ] = function ( url , config ) {
return this . request ( mergeConfig$1 ( config || { } , {
method : method ,
url : url ,
data : ( config || { } ) . data
} ) ) ;
} ;
} ) ;
utils$1 . forEach ( [ 'post' , 'put' , 'patch' ] , function forEachMethodWithData ( method ) {
/*eslint func-names:0*/
Axios$1 . prototype [ method ] = function ( url , data , config ) {
return this . request ( mergeConfig$1 ( config || { } , {
method : method ,
url : url ,
data : data
} ) ) ;
} ;
} ) ;
var Axios _1 = Axios$1 ;
var CancelToken _1 ;
var hasRequiredCancelToken ;
function requireCancelToken ( ) {
if ( hasRequiredCancelToken ) return CancelToken _1 ;
hasRequiredCancelToken = 1 ;
var Cancel = requireCancel ( ) ;
/ * *
* A ` CancelToken ` is an object that can be used to request cancellation of an operation .
*
* @ class
* @ param { Function } executor The executor function .
* /
function CancelToken ( executor ) {
if ( typeof executor !== 'function' ) {
throw new TypeError ( 'executor must be a function.' ) ;
}
var resolvePromise ;
this . promise = new Promise ( function promiseExecutor ( resolve ) {
resolvePromise = resolve ;
} ) ;
var token = this ;
// eslint-disable-next-line func-names
this . promise . then ( function ( cancel ) {
if ( ! token . _listeners ) return ;
var i ;
var l = token . _listeners . length ;
for ( i = 0 ; i < l ; i ++ ) {
token . _listeners [ i ] ( cancel ) ;
}
token . _listeners = null ;
} ) ;
// eslint-disable-next-line func-names
this . promise . then = function ( onfulfilled ) {
var _resolve ;
// eslint-disable-next-line func-names
var promise = new Promise ( function ( resolve ) {
token . subscribe ( resolve ) ;
_resolve = resolve ;
} ) . then ( onfulfilled ) ;
promise . cancel = function reject ( ) {
token . unsubscribe ( _resolve ) ;
} ;
return promise ;
} ;
executor ( function cancel ( message ) {
if ( token . reason ) {
// Cancellation has already been requested
return ;
}
token . reason = new Cancel ( message ) ;
resolvePromise ( token . reason ) ;
} ) ;
}
/ * *
* Throws a ` Cancel ` if cancellation has been requested .
* /
CancelToken . prototype . throwIfRequested = function throwIfRequested ( ) {
if ( this . reason ) {
throw this . reason ;
}
} ;
/ * *
* Subscribe to the cancel signal
* /
CancelToken . prototype . subscribe = function subscribe ( listener ) {
if ( this . reason ) {
listener ( this . reason ) ;
return ;
}
if ( this . _listeners ) {
this . _listeners . push ( listener ) ;
} else {
this . _listeners = [ listener ] ;
}
} ;
/ * *
* Unsubscribe from the cancel signal
* /
CancelToken . prototype . unsubscribe = function unsubscribe ( listener ) {
if ( ! this . _listeners ) {
return ;
}
var index = this . _listeners . indexOf ( listener ) ;
if ( index !== - 1 ) {
this . _listeners . splice ( index , 1 ) ;
}
} ;
/ * *
* Returns an object that contains a new ` CancelToken ` and a function that , when called ,
* cancels the ` CancelToken ` .
* /
CancelToken . source = function source ( ) {
var cancel ;
var token = new CancelToken ( function executor ( c ) {
cancel = c ;
} ) ;
return {
token : token ,
cancel : cancel
} ;
} ;
CancelToken _1 = CancelToken ;
return CancelToken _1 ;
}
var spread ;
var hasRequiredSpread ;
function requireSpread ( ) {
if ( hasRequiredSpread ) return spread ;
hasRequiredSpread = 1 ;
/ * *
* Syntactic sugar for invoking a function and expanding an array for arguments .
*
* Common use case would be to use ` Function.prototype.apply ` .
*
* ` ` ` js
* function f ( x , y , z ) { }
* var args = [ 1 , 2 , 3 ] ;
* f . apply ( null , args ) ;
* ` ` `
*
* With ` spread ` this example can be re - written .
*
* ` ` ` js
* spread ( function ( x , y , z ) { } ) ( [ 1 , 2 , 3 ] ) ;
* ` ` `
*
* @ param { Function } callback
* @ returns { Function }
* /
spread = function spread ( callback ) {
return function wrap ( arr ) {
return callback . apply ( null , arr ) ;
} ;
} ;
return spread ;
}
var isAxiosError ;
var hasRequiredIsAxiosError ;
function requireIsAxiosError ( ) {
if ( hasRequiredIsAxiosError ) return isAxiosError ;
hasRequiredIsAxiosError = 1 ;
var utils = utils$8 ;
/ * *
* Determines whether the payload is an error thrown by Axios
*
* @ param { * } payload The value to test
* @ returns { boolean } True if the payload is an error thrown by Axios , otherwise false
* /
isAxiosError = function isAxiosError ( payload ) {
return utils . isObject ( payload ) && ( payload . isAxiosError === true ) ;
} ;
return isAxiosError ;
}
var utils = utils$8 ;
var bind = bind$2 ;
var Axios = Axios _1 ;
var mergeConfig = mergeConfig$2 ;
var defaults = requireDefaults ( ) ;
/ * *
* Create an instance of Axios
*
* @ param { Object } defaultConfig The default config for the instance
* @ return { Axios } A new instance of Axios
* /
function createInstance ( defaultConfig ) {
var context = new Axios ( defaultConfig ) ;
var instance = bind ( Axios . prototype . request , context ) ;
// Copy axios.prototype to instance
utils . extend ( instance , Axios . prototype , context ) ;
// Copy context to instance
utils . extend ( instance , context ) ;
// Factory for creating new instances
instance . create = function create ( instanceConfig ) {
return createInstance ( mergeConfig ( defaultConfig , instanceConfig ) ) ;
} ;
return instance ;
}
// Create the default instance to be exported
var axios$2 = createInstance ( defaults ) ;
// Expose Axios class to allow class inheritance
axios$2 . Axios = Axios ;
// Expose Cancel & CancelToken
axios$2 . Cancel = requireCancel ( ) ;
axios$2 . CancelToken = requireCancelToken ( ) ;
axios$2 . isCancel = requireIsCancel ( ) ;
axios$2 . VERSION = requireData ( ) . version ;
// Expose all/spread
axios$2 . all = function all ( promises ) {
return Promise . all ( promises ) ;
} ;
axios$2 . spread = requireSpread ( ) ;
// Expose isAxiosError
axios$2 . isAxiosError = requireIsAxiosError ( ) ;
axios$3 . exports = axios$2 ;
// Allow use of default import syntax in TypeScript
axios$3 . exports . default = axios$2 ;
var axiosExports = axios$3 . exports ;
var axios = axiosExports ;
var axios$1 = /*@__PURE__*/ getDefaultExportFromCjs ( axios ) ;
var _nodeResolve _empty = { } ;
var _nodeResolve _empty$1 = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
default : _nodeResolve _empty
} ) ;
var require$$2 = /*@__PURE__*/ getAugmentedNamespace ( _nodeResolve _empty$1 ) ;
// hkp-client - A HKP client implementation in javascript
// Copyright (C) 2015 Tankred Hase
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3.0 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/ * *
* This class implements a client for the OpenPGP HTTP Keyserver Protocol ( HKP )
* in order to lookup and upload keys on standard public key servers .
* /
class HKP {
/ * *
* Initialize the HKP client and configure it with the key server url and fetch function .
* @ param { String } [ keyServerBaseUrl ] - The HKP key server base url including
* the protocol to use , e . g . 'https://pgp.mit.edu' ; defaults to
* openpgp . config . keyserver ( https : //keyserver.ubuntu.com)
* @ param { Object } [ config ] - Full configuration , defaults to openpgp . config
* /
constructor ( keyServerBaseUrl = 'https://keyserver.ubuntu.com' ) {
this . _baseUrl = keyServerBaseUrl ;
this . _fetch = typeof globalThis . fetch === 'function' ? globalThis . fetch : require$$2 ;
}
/ * *
* Search for a public key on the key server either by key ID or part of the user ID .
* @ param { String } options . keyId The long public key ID .
* @ param { String } options . query This can be any part of the key user ID such as name
* or email address .
* @ returns { String } The ascii armored public key .
* @ async
* /
lookup ( options ) {
let uri = this . _baseUrl + '/pks/lookup?op=get&options=mr&search=' ;
const fetch = this . _fetch ;
if ( options . keyId ) {
uri += '0x' + encodeURIComponent ( options . keyId ) ;
} else if ( options . query ) {
uri += encodeURIComponent ( options . query ) ;
} else {
throw new Error ( 'You must provide a query parameter!' ) ;
}
return fetch ( uri ) . then ( function ( response ) {
if ( response . status === 200 ) {
return response . text ( ) ;
}
} ) . then ( function ( publicKeyArmored ) {
if ( ! publicKeyArmored || publicKeyArmored . indexOf ( '-----END PGP PUBLIC KEY BLOCK-----' ) < 0 ) {
return ;
}
return publicKeyArmored . trim ( ) ;
} ) ;
}
/ * *
* Upload a public key to the server .
* @ param { String } publicKeyArmored - An ascii armored public key to be uploaded .
* @ returns { Promise }
* @ async
* /
upload ( publicKeyArmored ) {
const uri = this . _baseUrl + '/pks/add' ;
const fetch = this . _fetch ;
return fetch ( uri , {
method : 'post' ,
headers : {
'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
} ,
body : 'keytext=' + encodeURIComponent ( publicKeyArmored )
} ) ;
}
}
var hkp = HKP ;
var HKP$1 = /*@__PURE__*/ getDefaultExportFromCjs ( hkp ) ;
var _polyfillNode _crypto = { } ;
var _polyfillNode _crypto$1 = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
default : _polyfillNode _crypto
} ) ;
var require$$1 = /*@__PURE__*/ getAugmentedNamespace ( _polyfillNode _crypto$1 ) ;
// wkd-client - A WKD client implementation in javascript
// Copyright (C) 2018 Wiktor Kwapisiewicz
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3.0 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
/ * *
* This class implements a client for the Web Key Directory ( WKD ) protocol
* in order to lookup keys on designated servers .
* @ see https : //datatracker.ietf.org/doc/draft-koch-openpgp-webkey-service/
* /
class WKD {
/ * *
* Initialize the WKD client
* /
constructor ( ) {
this . _fetch = typeof globalThis . fetch === 'function' ? globalThis . fetch : require$$2 ;
const { subtle } = globalThis . crypto || require$$1 . webcrypto || new ( require$$2 . Crypto ) ( ) ;
this . _subtle = subtle ;
}
/ * *
* Search for a public key using Web Key Directory protocol .
* @ param { String } options . email User ' s email .
* @ returns { Uint8Array } The public key .
* @ async
* /
async lookup ( options ) {
const fetch = this . _fetch ;
if ( ! options . email ) {
throw new Error ( 'You must provide an email parameter!' ) ;
}
if ( typeof options . email !== 'string' || ! options . email . includes ( '@' ) ) {
throw new Error ( 'Invalid e-mail address.' ) ;
}
const [ localPart , domain ] = options . email . split ( '@' ) ;
const localPartEncoded = new TextEncoder ( ) . encode ( localPart . toLowerCase ( ) ) ;
const localPartHashed = new Uint8Array ( await this . _subtle . digest ( 'SHA-1' , localPartEncoded ) ) ;
const localPartBase32 = encodeZBase32 ( localPartHashed ) ;
const localPartEscaped = encodeURIComponent ( localPart ) ;
const urlAdvanced = ` https://openpgpkey. ${ domain } /.well-known/openpgpkey/ ${ domain } /hu/ ${ localPartBase32 } ?l= ${ localPartEscaped } ` ;
const urlDirect = ` https:// ${ domain } /.well-known/openpgpkey/hu/ ${ localPartBase32 } ?l= ${ localPartEscaped } ` ;
let response ;
try {
response = await fetch ( urlAdvanced ) ;
if ( response . status !== 200 ) {
throw new Error ( 'Advanced WKD lookup failed: ' + response . statusText ) ;
}
} catch ( err ) {
response = await fetch ( urlDirect ) ;
if ( response . status !== 200 ) {
throw new Error ( 'Direct WKD lookup failed: ' + response . statusText ) ;
}
}
return new Uint8Array ( await response . arrayBuffer ( ) ) ;
}
}
/ * *
* Encode input buffer using Z - Base32 encoding .
* See : https : //tools.ietf.org/html/rfc6189#section-5.1.6
*
* @ param { Uint8Array } data - The binary data to encode
* @ returns { String } Binary data encoded using Z - Base32 .
* /
function encodeZBase32 ( data ) {
if ( data . length === 0 ) {
return "" ;
}
const ALPHABET = "ybndrfg8ejkmcpqxot1uwisza345h769" ;
const SHIFT = 5 ;
const MASK = 31 ;
let buffer = data [ 0 ] ;
let index = 1 ;
let bitsLeft = 8 ;
let result = '' ;
while ( bitsLeft > 0 || index < data . length ) {
if ( bitsLeft < SHIFT ) {
if ( index < data . length ) {
buffer <<= 8 ;
buffer |= data [ index ++ ] & 0xff ;
bitsLeft += 8 ;
} else {
const pad = SHIFT - bitsLeft ;
buffer <<= pad ;
bitsLeft += pad ;
}
}
bitsLeft -= SHIFT ;
result += ALPHABET [ MASK & ( buffer >> bitsLeft ) ] ;
}
return result ;
}
var wkd = WKD ;
var WKD$1 = /*@__PURE__*/ getDefaultExportFromCjs ( wkd ) ;
/ *
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
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 .
* /
/ * *
* Functions related to OpenPGP Profiles
* @ module openpgp
* /
/ * *
* Fetch a public key using keyservers
* @ function
* @ param { string } identifier - Fingerprint or email address
* @ param { string } [ keyserverDomain = keys . openpgp . org ] - Domain of the keyserver
* @ returns { Promise < Profile > }
* @ example
* const key1 = doip . keys . fetchHKP ( 'alice@domain.tld' ) ;
* const key2 = doip . keys . fetchHKP ( '123abc123abc' ) ;
* /
async function fetchHKP ( identifier , keyserverDomain ) {
const keyserverBaseUrl = keyserverDomain
? ` https:// ${ keyserverDomain } `
: 'https://keys.openpgp.org' ;
const hkp = new HKP$1 ( keyserverBaseUrl ) ;
const lookupOpts = {
query : identifier
} ;
const publicKeyArmored = await hkp
. lookup ( lookupOpts )
. catch ( ( error ) => {
throw new Error ( ` Key does not exist or could not be fetched ( ${ error } ) ` )
} ) ;
if ( ! publicKeyArmored ) {
throw new Error ( 'Key does not exist or could not be fetched' )
}
const publicKey = await openpgp$1 . readKey ( {
armoredKey : publicKeyArmored
} )
. catch ( ( error ) => {
throw new Error ( ` Key could not be read ( ${ error } ) ` )
} ) ;
const profile = await parsePublicKey ( publicKey ) ;
profile . publicKey . fetch . method = PublicKeyFetchMethod . HKP ;
profile . publicKey . fetch . query = identifier ;
return profile
}
/ * *
* Fetch a public key using Web Key Directory
* @ function
* @ param { string } identifier - Identifier of format ' username @ domain . tld `
* @ returns { Promise < Profile > }
* @ example
* const key = doip . keys . fetchWKD ( 'alice@domain.tld' ) ;
* /
async function fetchWKD ( identifier ) {
const wkd = new WKD$1 ( ) ;
const lookupOpts = {
email : identifier
} ;
const publicKeyBinary = await wkd
. lookup ( lookupOpts )
. catch ( ( /** @type {Error} */ error ) => {
throw new Error ( ` Key does not exist or could not be fetched ( ${ error } ) ` )
} ) ;
if ( ! publicKeyBinary ) {
throw new Error ( 'Key does not exist or could not be fetched' )
}
const publicKey = await openpgp$1 . readKey ( {
binaryKey : publicKeyBinary
} )
. catch ( ( error ) => {
throw new Error ( ` Key could not be read ( ${ error } ) ` )
} ) ;
const profile = await parsePublicKey ( publicKey ) ;
profile . publicKey . fetch . method = PublicKeyFetchMethod . WKD ;
profile . publicKey . fetch . query = identifier ;
return profile
}
/ * *
* Fetch a public key from Keybase
* @ function
* @ param { string } username - Keybase username
* @ param { string } fingerprint - Fingerprint of key
* @ returns { Promise < Profile > }
* @ example
* const key = doip . keys . fetchKeybase ( 'alice' , '123abc123abc' ) ;
* /
async function fetchKeybase ( username , fingerprint ) {
const keyLink = ` https://keybase.io/ ${ username } /pgp_keys.asc?fingerprint= ${ fingerprint } ` ;
let rawKeyContent ;
try {
rawKeyContent = await axios$1 . get (
keyLink ,
{
responseType : 'text'
}
)
. then ( ( /** @type {import('axios').AxiosResponse} */ response ) => {
if ( response . status === 200 ) {
return response
}
} )
. then ( ( /** @type {import('axios').AxiosResponse} */ response ) => response . data ) ;
} catch ( e ) {
throw new Error ( ` Error fetching Keybase key: ${ e . message } ` )
}
const publicKey = await openpgp$1 . readKey ( {
armoredKey : rawKeyContent
} )
. catch ( ( error ) => {
throw new Error ( ` Key does not exist or could not be fetched ( ${ error } ) ` )
} ) ;
const profile = await parsePublicKey ( publicKey ) ;
profile . publicKey . fetch . method = PublicKeyFetchMethod . HTTP ;
profile . publicKey . fetch . query = null ;
profile . publicKey . fetch . resolvedUrl = keyLink ;
return profile
}
/ * *
* Get a public key from plaintext data
* @ function
* @ param { string } rawKeyContent - Plaintext ASCII - formatted public key data
* @ returns { Promise < Profile > }
* @ example
* const plainkey = ` -----BEGIN PGP PUBLIC KEY BLOCK-----
*
* mQINBF0mIsIBEADacleiyiV + z6FIunvLWrO6ZETxGNVpqM + WbBQKdW1BVrJBBolg
* [ ... ]
* = 6 lib
* -- -- - END PGP PUBLIC KEY BLOCK -- -- - `
* const key = doip . keys . fetchPlaintext ( plainkey ) ;
* /
async function fetchPlaintext ( rawKeyContent ) {
const publicKey = await openpgp$1 . readKey ( {
armoredKey : rawKeyContent
} )
. catch ( ( error ) => {
throw new Error ( ` Key could not be read ( ${ error } ) ` )
} ) ;
const profile = await parsePublicKey ( publicKey ) ;
return profile
}
/ * *
* Fetch a public key using an URI
* @ function
* @ param { string } uri - URI that defines the location of the key
* @ returns { Promise < Profile > }
* @ example
* const key1 = doip . keys . fetchURI ( 'hkp:alice@domain.tld' ) ;
* const key2 = doip . keys . fetchURI ( 'hkp:123abc123abc' ) ;
* const key3 = doip . keys . fetchURI ( 'wkd:alice@domain.tld' ) ;
* /
async function fetchURI ( uri ) {
if ( ! validUrlExports . isUri ( uri ) ) {
throw new Error ( 'Invalid URI' )
}
const re = /([a-zA-Z0-9]*):([a-zA-Z0-9@._=+-]*)(?::([a-zA-Z0-9@._=+-]*))?/ ;
const match = uri . match ( re ) ;
if ( ! match [ 1 ] ) {
throw new Error ( 'Invalid URI' )
}
switch ( match [ 1 ] ) {
case 'hkp' :
return await fetchHKP (
match [ 3 ] ? match [ 3 ] : match [ 2 ] ,
match [ 3 ] ? match [ 2 ] : null
)
case 'wkd' :
return await fetchWKD ( match [ 2 ] )
case 'kb' :
return await fetchKeybase ( match [ 2 ] , match . length >= 4 ? match [ 3 ] : null )
default :
throw new Error ( 'Invalid URI protocol' )
}
}
/ * *
* Fetch a public key
*
* This function will attempt to detect the identifier and fetch the key
* accordingly . If the identifier is an email address , it will first try and
* fetch the key using WKD and then HKP . Otherwise , it will try HKP only .
*
* This function will also try and parse the input as a plaintext key
* @ function
* @ param { string } identifier - URI that defines the location of the key
* @ returns { Promise < Profile > }
* @ example
* const key1 = doip . keys . fetch ( 'alice@domain.tld' ) ;
* const key2 = doip . keys . fetch ( '123abc123abc' ) ;
* /
async function fetch$1 ( identifier ) {
const re = /([a-zA-Z0-9@._=+-]*)(?::([a-zA-Z0-9@._=+-]*))?/ ;
const match = identifier . match ( re ) ;
let profile = null ;
// Attempt plaintext
try {
profile = await fetchPlaintext ( identifier ) ;
} catch ( e ) { }
// Attempt WKD
if ( ! profile && identifier . includes ( '@' ) ) {
try {
profile = await fetchWKD ( match [ 1 ] ) ;
} catch ( e ) { }
}
// Attempt HKP
if ( ! profile ) {
profile = await fetchHKP (
match [ 2 ] ? match [ 2 ] : match [ 1 ] ,
match [ 2 ] ? match [ 1 ] : null
) ;
}
if ( ! profile ) {
throw new Error ( 'Key does not exist or could not be fetched' )
}
return profile
}
/ * *
2023-07-13 02:41:31 -06:00
* Process a public key to get a profile
2023-07-09 04:05:21 -06:00
* @ function
2023-07-13 02:41:31 -06:00
* @ param { PublicKey } publicKey - The public key to parse
2023-07-09 04:05:21 -06:00
* @ returns { Promise < Profile > }
* @ example
* const key = doip . keys . fetchURI ( 'hkp:alice@domain.tld' ) ;
2023-07-13 02:41:31 -06:00
* const profile = doip . keys . parsePublicKey ( key ) ;
* profile . personas [ 0 ] . claims . forEach ( claim => {
2023-07-09 04:05:21 -06:00
* console . log ( claim . uri ) ;
* } ) ;
* /
async function parsePublicKey ( publicKey ) {
if ( ! ( publicKey && ( publicKey instanceof openpgp$1 . PublicKey ) ) ) {
throw new Error ( 'Invalid public key' )
}
const fingerprint = publicKey . getFingerprint ( ) ;
const primaryUser = await publicKey . getPrimaryUser ( ) ;
const users = publicKey . users ;
const personas = [ ] ;
users . forEach ( ( user , i ) => {
2023-09-18 09:46:54 -06:00
if ( ! user . userID ) return
2023-07-09 04:05:21 -06:00
const pe = new Persona ( user . userID . name , [ ] ) ;
pe . setIdentifier ( user . userID . userID ) ;
pe . setDescription ( user . userID . comment ) ;
pe . setEmailAddress ( user . userID . email ) ;
if ( 'selfCertifications' in user && user . selfCertifications . length > 0 ) {
const selfCertification = user . selfCertifications . sort ( ( e1 , e2 ) => e2 . created . getTime ( ) - e1 . created . getTime ( ) ) [ 0 ] ;
if ( selfCertification . revoked ) {
pe . revoke ( ) ;
}
const notations = selfCertification . rawNotations ;
pe . claims = notations
. filter (
( { name , humanReadable } ) =>
humanReadable && ( name === 'proof@ariadne.id' || name === 'proof@metacode.biz' )
)
. map (
( { value } ) =>
new Claim ( new TextDecoder ( ) . decode ( value ) , ` openpgp4fpr: ${ fingerprint } ` )
) ;
}
personas . push ( pe ) ;
} ) ;
2023-07-13 02:41:31 -06:00
const profile = new Profile ( ProfileType . OPENPGP , ` openpgp4fpr: ${ fingerprint } ` , personas ) ;
profile . primaryPersonaIndex = primaryUser . index ;
profile . publicKey . keyType = PublicKeyType . OPENPGP ;
profile . publicKey . fingerprint = fingerprint ;
profile . publicKey . encoding = PublicKeyEncoding . ARMORED _PGP ;
profile . publicKey . encodedKey = publicKey . armor ( ) ;
profile . publicKey . key = publicKey ;
2023-07-09 04:05:21 -06:00
2023-07-13 02:41:31 -06:00
return profile
2023-07-09 04:05:21 -06:00
}
var openpgp = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
fetch : fetch$1 ,
fetchHKP : fetchHKP ,
fetchKeybase : fetchKeybase ,
fetchPlaintext : fetchPlaintext ,
fetchURI : fetchURI ,
2023-07-13 02:41:31 -06:00
fetchWKD : fetchWKD ,
parsePublicKey : parsePublicKey
2023-07-09 04:05:21 -06:00
} ) ;
var crypto$1 = crypto ;
const isCryptoKey = ( key ) => key instanceof CryptoKey ;
const digest = async ( algorithm , data ) => {
const subtleDigest = ` SHA- ${ algorithm . slice ( - 3 ) } ` ;
return new Uint8Array ( await crypto$1 . subtle . digest ( subtleDigest , data ) ) ;
} ;
const encoder = new TextEncoder ( ) ;
const decoder = new TextDecoder ( ) ;
function concat ( ... buffers ) {
const size = buffers . reduce ( ( acc , { length } ) => acc + length , 0 ) ;
const buf = new Uint8Array ( size ) ;
let i = 0 ;
buffers . forEach ( ( buffer ) => {
buf . set ( buffer , i ) ;
i += buffer . length ;
} ) ;
return buf ;
}
const encodeBase64 = ( input ) => {
let unencoded = input ;
if ( typeof unencoded === 'string' ) {
unencoded = encoder . encode ( unencoded ) ;
}
const CHUNK _SIZE = 0x8000 ;
const arr = [ ] ;
for ( let i = 0 ; i < unencoded . length ; i += CHUNK _SIZE ) {
arr . push ( String . fromCharCode . apply ( null , unencoded . subarray ( i , i + CHUNK _SIZE ) ) ) ;
}
return btoa ( arr . join ( '' ) ) ;
} ;
const encode = ( input ) => {
return encodeBase64 ( input ) . replace ( /=/g , '' ) . replace ( /\+/g , '-' ) . replace ( /\//g , '_' ) ;
} ;
const decodeBase64 = ( encoded ) => {
const binary = atob ( encoded ) ;
const bytes = new Uint8Array ( binary . length ) ;
for ( let i = 0 ; i < binary . length ; i ++ ) {
bytes [ i ] = binary . charCodeAt ( i ) ;
}
return bytes ;
} ;
const decode$1 = ( input ) => {
let encoded = input ;
if ( encoded instanceof Uint8Array ) {
encoded = decoder . decode ( encoded ) ;
}
encoded = encoded . replace ( /-/g , '+' ) . replace ( /_/g , '/' ) . replace ( /\s/g , '' ) ;
try {
return decodeBase64 ( encoded ) ;
}
catch ( _a ) {
throw new TypeError ( 'The input to be decoded is not correctly encoded.' ) ;
}
} ;
class JOSEError extends Error {
static get code ( ) {
return 'ERR_JOSE_GENERIC' ;
}
constructor ( message ) {
var _a ;
super ( message ) ;
this . code = 'ERR_JOSE_GENERIC' ;
this . name = this . constructor . name ;
( _a = Error . captureStackTrace ) === null || _a === void 0 ? void 0 : _a . call ( Error , this , this . constructor ) ;
}
}
class JOSEAlgNotAllowed extends JOSEError {
constructor ( ) {
super ( ... arguments ) ;
this . code = 'ERR_JOSE_ALG_NOT_ALLOWED' ;
}
static get code ( ) {
return 'ERR_JOSE_ALG_NOT_ALLOWED' ;
}
}
class JOSENotSupported extends JOSEError {
constructor ( ) {
super ( ... arguments ) ;
this . code = 'ERR_JOSE_NOT_SUPPORTED' ;
}
static get code ( ) {
return 'ERR_JOSE_NOT_SUPPORTED' ;
}
}
class JWSInvalid extends JOSEError {
constructor ( ) {
super ( ... arguments ) ;
this . code = 'ERR_JWS_INVALID' ;
}
static get code ( ) {
return 'ERR_JWS_INVALID' ;
}
}
class JWKInvalid extends JOSEError {
constructor ( ) {
super ( ... arguments ) ;
this . code = 'ERR_JWK_INVALID' ;
}
static get code ( ) {
return 'ERR_JWK_INVALID' ;
}
}
class JWSSignatureVerificationFailed extends JOSEError {
constructor ( ) {
super ( ... arguments ) ;
this . code = 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED' ;
this . message = 'signature verification failed' ;
}
static get code ( ) {
return 'ERR_JWS_SIGNATURE_VERIFICATION_FAILED' ;
}
}
function unusable ( name , prop = 'algorithm.name' ) {
return new TypeError ( ` CryptoKey does not support this operation, its ${ prop } must be ${ name } ` ) ;
}
function isAlgorithm ( algorithm , name ) {
return algorithm . name === name ;
}
function getHashLength ( hash ) {
return parseInt ( hash . name . slice ( 4 ) , 10 ) ;
}
function getNamedCurve ( alg ) {
switch ( alg ) {
case 'ES256' :
return 'P-256' ;
case 'ES384' :
return 'P-384' ;
case 'ES512' :
return 'P-521' ;
default :
throw new Error ( 'unreachable' ) ;
}
}
function checkUsage ( key , usages ) {
if ( usages . length && ! usages . some ( ( expected ) => key . usages . includes ( expected ) ) ) {
let msg = 'CryptoKey does not support this operation, its usages must include ' ;
if ( usages . length > 2 ) {
const last = usages . pop ( ) ;
msg += ` one of ${ usages . join ( ', ' ) } , or ${ last } . ` ;
}
else if ( usages . length === 2 ) {
msg += ` one of ${ usages [ 0 ] } or ${ usages [ 1 ] } . ` ;
}
else {
msg += ` ${ usages [ 0 ] } . ` ;
}
throw new TypeError ( msg ) ;
}
}
function checkSigCryptoKey ( key , alg , ... usages ) {
switch ( alg ) {
case 'HS256' :
case 'HS384' :
case 'HS512' : {
if ( ! isAlgorithm ( key . algorithm , 'HMAC' ) )
throw unusable ( 'HMAC' ) ;
const expected = parseInt ( alg . slice ( 2 ) , 10 ) ;
const actual = getHashLength ( key . algorithm . hash ) ;
if ( actual !== expected )
throw unusable ( ` SHA- ${ expected } ` , 'algorithm.hash' ) ;
break ;
}
case 'RS256' :
case 'RS384' :
case 'RS512' : {
if ( ! isAlgorithm ( key . algorithm , 'RSASSA-PKCS1-v1_5' ) )
throw unusable ( 'RSASSA-PKCS1-v1_5' ) ;
const expected = parseInt ( alg . slice ( 2 ) , 10 ) ;
const actual = getHashLength ( key . algorithm . hash ) ;
if ( actual !== expected )
throw unusable ( ` SHA- ${ expected } ` , 'algorithm.hash' ) ;
break ;
}
case 'PS256' :
case 'PS384' :
case 'PS512' : {
if ( ! isAlgorithm ( key . algorithm , 'RSA-PSS' ) )
throw unusable ( 'RSA-PSS' ) ;
const expected = parseInt ( alg . slice ( 2 ) , 10 ) ;
const actual = getHashLength ( key . algorithm . hash ) ;
if ( actual !== expected )
throw unusable ( ` SHA- ${ expected } ` , 'algorithm.hash' ) ;
break ;
}
case 'EdDSA' : {
if ( key . algorithm . name !== 'Ed25519' && key . algorithm . name !== 'Ed448' ) {
throw unusable ( 'Ed25519 or Ed448' ) ;
}
break ;
}
case 'ES256' :
case 'ES384' :
case 'ES512' : {
if ( ! isAlgorithm ( key . algorithm , 'ECDSA' ) )
throw unusable ( 'ECDSA' ) ;
const expected = getNamedCurve ( alg ) ;
const actual = key . algorithm . namedCurve ;
if ( actual !== expected )
throw unusable ( expected , 'algorithm.namedCurve' ) ;
break ;
}
default :
throw new TypeError ( 'CryptoKey does not support this operation' ) ;
}
checkUsage ( key , usages ) ;
}
function message ( msg , actual , ... types ) {
if ( types . length > 2 ) {
const last = types . pop ( ) ;
msg += ` one of type ${ types . join ( ', ' ) } , or ${ last } . ` ;
}
else if ( types . length === 2 ) {
msg += ` one of type ${ types [ 0 ] } or ${ types [ 1 ] } . ` ;
}
else {
msg += ` of type ${ types [ 0 ] } . ` ;
}
if ( actual == null ) {
msg += ` Received ${ actual } ` ;
}
else if ( typeof actual === 'function' && actual . name ) {
msg += ` Received function ${ actual . name } ` ;
}
else if ( typeof actual === 'object' && actual != null ) {
if ( actual . constructor && actual . constructor . name ) {
msg += ` Received an instance of ${ actual . constructor . name } ` ;
}
}
return msg ;
}
var invalidKeyInput = ( actual , ... types ) => {
return message ( 'Key must be ' , actual , ... types ) ;
} ;
function withAlg ( alg , actual , ... types ) {
return message ( ` Key for the ${ alg } algorithm must be ` , actual , ... types ) ;
}
var isKeyLike = ( key ) => {
return isCryptoKey ( key ) ;
} ;
const types = [ 'CryptoKey' ] ;
const isDisjoint = ( ... headers ) => {
const sources = headers . filter ( Boolean ) ;
if ( sources . length === 0 || sources . length === 1 ) {
return true ;
}
let acc ;
for ( const header of sources ) {
const parameters = Object . keys ( header ) ;
if ( ! acc || acc . size === 0 ) {
acc = new Set ( parameters ) ;
continue ;
}
for ( const parameter of parameters ) {
if ( acc . has ( parameter ) ) {
return false ;
}
acc . add ( parameter ) ;
}
}
return true ;
} ;
function isObjectLike ( value ) {
return typeof value === 'object' && value !== null ;
}
function isObject ( input ) {
if ( ! isObjectLike ( input ) || Object . prototype . toString . call ( input ) !== '[object Object]' ) {
return false ;
}
if ( Object . getPrototypeOf ( input ) === null ) {
return true ;
}
let proto = input ;
while ( Object . getPrototypeOf ( proto ) !== null ) {
proto = Object . getPrototypeOf ( proto ) ;
}
return Object . getPrototypeOf ( input ) === proto ;
}
var checkKeyLength = ( alg , key ) => {
if ( alg . startsWith ( 'RS' ) || alg . startsWith ( 'PS' ) ) {
const { modulusLength } = key . algorithm ;
if ( typeof modulusLength !== 'number' || modulusLength < 2048 ) {
throw new TypeError ( ` ${ alg } requires key modulusLength to be 2048 bits or larger ` ) ;
}
}
} ;
function subtleMapping ( jwk ) {
let algorithm ;
let keyUsages ;
switch ( jwk . kty ) {
case 'oct' : {
switch ( jwk . alg ) {
case 'HS256' :
case 'HS384' :
case 'HS512' :
algorithm = { name : 'HMAC' , hash : ` SHA- ${ jwk . alg . slice ( - 3 ) } ` } ;
keyUsages = [ 'sign' , 'verify' ] ;
break ;
case 'A128CBC-HS256' :
case 'A192CBC-HS384' :
case 'A256CBC-HS512' :
throw new JOSENotSupported ( ` ${ jwk . alg } keys cannot be imported as CryptoKey instances ` ) ;
case 'A128GCM' :
case 'A192GCM' :
case 'A256GCM' :
case 'A128GCMKW' :
case 'A192GCMKW' :
case 'A256GCMKW' :
algorithm = { name : 'AES-GCM' } ;
keyUsages = [ 'encrypt' , 'decrypt' ] ;
break ;
case 'A128KW' :
case 'A192KW' :
case 'A256KW' :
algorithm = { name : 'AES-KW' } ;
keyUsages = [ 'wrapKey' , 'unwrapKey' ] ;
break ;
case 'PBES2-HS256+A128KW' :
case 'PBES2-HS384+A192KW' :
case 'PBES2-HS512+A256KW' :
algorithm = { name : 'PBKDF2' } ;
keyUsages = [ 'deriveBits' ] ;
break ;
default :
throw new JOSENotSupported ( 'Invalid or unsupported JWK "alg" (Algorithm) Parameter value' ) ;
}
break ;
}
case 'RSA' : {
switch ( jwk . alg ) {
case 'PS256' :
case 'PS384' :
case 'PS512' :
algorithm = { name : 'RSA-PSS' , hash : ` SHA- ${ jwk . alg . slice ( - 3 ) } ` } ;
keyUsages = jwk . d ? [ 'sign' ] : [ 'verify' ] ;
break ;
case 'RS256' :
case 'RS384' :
case 'RS512' :
algorithm = { name : 'RSASSA-PKCS1-v1_5' , hash : ` SHA- ${ jwk . alg . slice ( - 3 ) } ` } ;
keyUsages = jwk . d ? [ 'sign' ] : [ 'verify' ] ;
break ;
case 'RSA-OAEP' :
case 'RSA-OAEP-256' :
case 'RSA-OAEP-384' :
case 'RSA-OAEP-512' :
algorithm = {
name : 'RSA-OAEP' ,
hash : ` SHA- ${ parseInt ( jwk . alg . slice ( - 3 ) , 10 ) || 1 } ` ,
} ;
keyUsages = jwk . d ? [ 'decrypt' , 'unwrapKey' ] : [ 'encrypt' , 'wrapKey' ] ;
break ;
default :
throw new JOSENotSupported ( 'Invalid or unsupported JWK "alg" (Algorithm) Parameter value' ) ;
}
break ;
}
case 'EC' : {
switch ( jwk . alg ) {
case 'ES256' :
algorithm = { name : 'ECDSA' , namedCurve : 'P-256' } ;
keyUsages = jwk . d ? [ 'sign' ] : [ 'verify' ] ;
break ;
case 'ES384' :
algorithm = { name : 'ECDSA' , namedCurve : 'P-384' } ;
keyUsages = jwk . d ? [ 'sign' ] : [ 'verify' ] ;
break ;
case 'ES512' :
algorithm = { name : 'ECDSA' , namedCurve : 'P-521' } ;
keyUsages = jwk . d ? [ 'sign' ] : [ 'verify' ] ;
break ;
case 'ECDH-ES' :
case 'ECDH-ES+A128KW' :
case 'ECDH-ES+A192KW' :
case 'ECDH-ES+A256KW' :
algorithm = { name : 'ECDH' , namedCurve : jwk . crv } ;
keyUsages = jwk . d ? [ 'deriveBits' ] : [ ] ;
break ;
default :
throw new JOSENotSupported ( 'Invalid or unsupported JWK "alg" (Algorithm) Parameter value' ) ;
}
break ;
}
case 'OKP' : {
switch ( jwk . alg ) {
case 'EdDSA' :
algorithm = { name : jwk . crv } ;
keyUsages = jwk . d ? [ 'sign' ] : [ 'verify' ] ;
break ;
case 'ECDH-ES' :
case 'ECDH-ES+A128KW' :
case 'ECDH-ES+A192KW' :
case 'ECDH-ES+A256KW' :
algorithm = { name : jwk . crv } ;
keyUsages = jwk . d ? [ 'deriveBits' ] : [ ] ;
break ;
default :
throw new JOSENotSupported ( 'Invalid or unsupported JWK "alg" (Algorithm) Parameter value' ) ;
}
break ;
}
default :
throw new JOSENotSupported ( 'Invalid or unsupported JWK "kty" (Key Type) Parameter value' ) ;
}
return { algorithm , keyUsages } ;
}
2023-07-13 02:41:31 -06:00
const parse$2 = async ( jwk ) => {
2023-07-09 04:05:21 -06:00
var _a , _b ;
if ( ! jwk . alg ) {
throw new TypeError ( '"alg" argument is required when "jwk.alg" is not present' ) ;
}
const { algorithm , keyUsages } = subtleMapping ( jwk ) ;
const rest = [
algorithm ,
( _a = jwk . ext ) !== null && _a !== void 0 ? _a : false ,
( _b = jwk . key _ops ) !== null && _b !== void 0 ? _b : keyUsages ,
] ;
if ( algorithm . name === 'PBKDF2' ) {
return crypto$1 . subtle . importKey ( 'raw' , decode$1 ( jwk . k ) , ... rest ) ;
}
const keyData = { ... jwk } ;
delete keyData . alg ;
delete keyData . use ;
return crypto$1 . subtle . importKey ( 'jwk' , keyData , ... rest ) ;
} ;
2023-07-13 02:41:31 -06:00
var asKeyObject = parse$2 ;
2023-07-09 04:05:21 -06:00
async function importJWK ( jwk , alg , octAsKeyObject ) {
var _a ;
if ( ! isObject ( jwk ) ) {
throw new TypeError ( 'JWK must be an object' ) ;
}
alg || ( alg = jwk . alg ) ;
switch ( jwk . kty ) {
case 'oct' :
if ( typeof jwk . k !== 'string' || ! jwk . k ) {
throw new TypeError ( 'missing "k" (Key Value) Parameter value' ) ;
}
octAsKeyObject !== null && octAsKeyObject !== void 0 ? octAsKeyObject : ( octAsKeyObject = jwk . ext !== true ) ;
if ( octAsKeyObject ) {
return asKeyObject ( { ... jwk , alg , ext : ( _a = jwk . ext ) !== null && _a !== void 0 ? _a : false } ) ;
}
return decode$1 ( jwk . k ) ;
case 'RSA' :
if ( jwk . oth !== undefined ) {
throw new JOSENotSupported ( 'RSA JWK "oth" (Other Primes Info) Parameter value is not supported' ) ;
}
case 'EC' :
case 'OKP' :
return asKeyObject ( { ... jwk , alg } ) ;
default :
throw new JOSENotSupported ( 'Unsupported "kty" (Key Type) Parameter value' ) ;
}
}
const symmetricTypeCheck = ( alg , key ) => {
if ( key instanceof Uint8Array )
return ;
if ( ! isKeyLike ( key ) ) {
throw new TypeError ( withAlg ( alg , key , ... types , 'Uint8Array' ) ) ;
}
if ( key . type !== 'secret' ) {
throw new TypeError ( ` ${ types . join ( ' or ' ) } instances for symmetric algorithms must be of type "secret" ` ) ;
}
} ;
const asymmetricTypeCheck = ( alg , key , usage ) => {
if ( ! isKeyLike ( key ) ) {
throw new TypeError ( withAlg ( alg , key , ... types ) ) ;
}
if ( key . type === 'secret' ) {
throw new TypeError ( ` ${ types . join ( ' or ' ) } instances for asymmetric algorithms must not be of type "secret" ` ) ;
}
if ( usage === 'sign' && key . type === 'public' ) {
throw new TypeError ( ` ${ types . join ( ' or ' ) } instances for asymmetric algorithm signing must be of type "private" ` ) ;
}
if ( usage === 'decrypt' && key . type === 'public' ) {
throw new TypeError ( ` ${ types . join ( ' or ' ) } instances for asymmetric algorithm decryption must be of type "private" ` ) ;
}
if ( key . algorithm && usage === 'verify' && key . type === 'private' ) {
throw new TypeError ( ` ${ types . join ( ' or ' ) } instances for asymmetric algorithm verifying must be of type "public" ` ) ;
}
if ( key . algorithm && usage === 'encrypt' && key . type === 'private' ) {
throw new TypeError ( ` ${ types . join ( ' or ' ) } instances for asymmetric algorithm encryption must be of type "public" ` ) ;
}
} ;
const checkKeyType = ( alg , key , usage ) => {
const symmetric = alg . startsWith ( 'HS' ) ||
alg === 'dir' ||
alg . startsWith ( 'PBES2' ) ||
/^A\d{3}(?:GCM)?KW$/ . test ( alg ) ;
if ( symmetric ) {
symmetricTypeCheck ( alg , key ) ;
}
else {
asymmetricTypeCheck ( alg , key , usage ) ;
}
} ;
function validateCrit ( Err , recognizedDefault , recognizedOption , protectedHeader , joseHeader ) {
if ( joseHeader . crit !== undefined && protectedHeader . crit === undefined ) {
throw new Err ( '"crit" (Critical) Header Parameter MUST be integrity protected' ) ;
}
if ( ! protectedHeader || protectedHeader . crit === undefined ) {
return new Set ( ) ;
}
if ( ! Array . isArray ( protectedHeader . crit ) ||
protectedHeader . crit . length === 0 ||
protectedHeader . crit . some ( ( input ) => typeof input !== 'string' || input . length === 0 ) ) {
throw new Err ( '"crit" (Critical) Header Parameter MUST be an array of non-empty strings when present' ) ;
}
let recognized ;
if ( recognizedOption !== undefined ) {
recognized = new Map ( [ ... Object . entries ( recognizedOption ) , ... recognizedDefault . entries ( ) ] ) ;
}
else {
recognized = recognizedDefault ;
}
for ( const parameter of protectedHeader . crit ) {
if ( ! recognized . has ( parameter ) ) {
throw new JOSENotSupported ( ` Extension Header Parameter " ${ parameter } " is not recognized ` ) ;
}
if ( joseHeader [ parameter ] === undefined ) {
throw new Err ( ` Extension Header Parameter " ${ parameter } " is missing ` ) ;
}
else if ( recognized . get ( parameter ) && protectedHeader [ parameter ] === undefined ) {
throw new Err ( ` Extension Header Parameter " ${ parameter } " MUST be integrity protected ` ) ;
}
}
return new Set ( protectedHeader . crit ) ;
}
const validateAlgorithms = ( option , algorithms ) => {
if ( algorithms !== undefined &&
( ! Array . isArray ( algorithms ) || algorithms . some ( ( s ) => typeof s !== 'string' ) ) ) {
throw new TypeError ( ` " ${ option } " option must be an array of strings ` ) ;
}
if ( ! algorithms ) {
return undefined ;
}
return new Set ( algorithms ) ;
} ;
function subtleDsa ( alg , algorithm ) {
const hash = ` SHA- ${ alg . slice ( - 3 ) } ` ;
switch ( alg ) {
case 'HS256' :
case 'HS384' :
case 'HS512' :
return { hash , name : 'HMAC' } ;
case 'PS256' :
case 'PS384' :
case 'PS512' :
return { hash , name : 'RSA-PSS' , saltLength : alg . slice ( - 3 ) >> 3 } ;
case 'RS256' :
case 'RS384' :
case 'RS512' :
return { hash , name : 'RSASSA-PKCS1-v1_5' } ;
case 'ES256' :
case 'ES384' :
case 'ES512' :
return { hash , name : 'ECDSA' , namedCurve : algorithm . namedCurve } ;
case 'EdDSA' :
return { name : algorithm . name } ;
default :
throw new JOSENotSupported ( ` alg ${ alg } is not supported either by JOSE or your javascript runtime ` ) ;
}
}
function getCryptoKey ( alg , key , usage ) {
if ( isCryptoKey ( key ) ) {
checkSigCryptoKey ( key , alg , usage ) ;
return key ;
}
if ( key instanceof Uint8Array ) {
if ( ! alg . startsWith ( 'HS' ) ) {
throw new TypeError ( invalidKeyInput ( key , ... types ) ) ;
}
return crypto$1 . subtle . importKey ( 'raw' , key , { hash : ` SHA- ${ alg . slice ( - 3 ) } ` , name : 'HMAC' } , false , [ usage ] ) ;
}
throw new TypeError ( invalidKeyInput ( key , ... types , 'Uint8Array' ) ) ;
}
const verify = async ( alg , key , signature , data ) => {
const cryptoKey = await getCryptoKey ( alg , key , 'verify' ) ;
checkKeyLength ( alg , cryptoKey ) ;
const algorithm = subtleDsa ( alg , cryptoKey . algorithm ) ;
try {
return await crypto$1 . subtle . verify ( algorithm , cryptoKey , signature , data ) ;
}
catch ( _a ) {
return false ;
}
} ;
async function flattenedVerify ( jws , key , options ) {
var _a ;
if ( ! isObject ( jws ) ) {
throw new JWSInvalid ( 'Flattened JWS must be an object' ) ;
}
if ( jws . protected === undefined && jws . header === undefined ) {
throw new JWSInvalid ( 'Flattened JWS must have either of the "protected" or "header" members' ) ;
}
if ( jws . protected !== undefined && typeof jws . protected !== 'string' ) {
throw new JWSInvalid ( 'JWS Protected Header incorrect type' ) ;
}
if ( jws . payload === undefined ) {
throw new JWSInvalid ( 'JWS Payload missing' ) ;
}
if ( typeof jws . signature !== 'string' ) {
throw new JWSInvalid ( 'JWS Signature missing or incorrect type' ) ;
}
if ( jws . header !== undefined && ! isObject ( jws . header ) ) {
throw new JWSInvalid ( 'JWS Unprotected Header incorrect type' ) ;
}
let parsedProt = { } ;
if ( jws . protected ) {
try {
const protectedHeader = decode$1 ( jws . protected ) ;
parsedProt = JSON . parse ( decoder . decode ( protectedHeader ) ) ;
}
catch ( _b ) {
throw new JWSInvalid ( 'JWS Protected Header is invalid' ) ;
}
}
if ( ! isDisjoint ( parsedProt , jws . header ) ) {
throw new JWSInvalid ( 'JWS Protected and JWS Unprotected Header Parameter names must be disjoint' ) ;
}
const joseHeader = {
... parsedProt ,
... jws . header ,
} ;
const extensions = validateCrit ( JWSInvalid , new Map ( [ [ 'b64' , true ] ] ) , options === null || options === void 0 ? void 0 : options . crit , parsedProt , joseHeader ) ;
let b64 = true ;
if ( extensions . has ( 'b64' ) ) {
b64 = parsedProt . b64 ;
if ( typeof b64 !== 'boolean' ) {
throw new JWSInvalid ( 'The "b64" (base64url-encode payload) Header Parameter must be a boolean' ) ;
}
}
const { alg } = joseHeader ;
if ( typeof alg !== 'string' || ! alg ) {
throw new JWSInvalid ( 'JWS "alg" (Algorithm) Header Parameter missing or invalid' ) ;
}
const algorithms = options && validateAlgorithms ( 'algorithms' , options . algorithms ) ;
if ( algorithms && ! algorithms . has ( alg ) ) {
throw new JOSEAlgNotAllowed ( '"alg" (Algorithm) Header Parameter not allowed' ) ;
}
if ( b64 ) {
if ( typeof jws . payload !== 'string' ) {
throw new JWSInvalid ( 'JWS Payload must be a string' ) ;
}
}
else if ( typeof jws . payload !== 'string' && ! ( jws . payload instanceof Uint8Array ) ) {
throw new JWSInvalid ( 'JWS Payload must be a string or an Uint8Array instance' ) ;
}
let resolvedKey = false ;
if ( typeof key === 'function' ) {
key = await key ( parsedProt , jws ) ;
resolvedKey = true ;
}
checkKeyType ( alg , key , 'verify' ) ;
const data = concat ( encoder . encode ( ( _a = jws . protected ) !== null && _a !== void 0 ? _a : '' ) , encoder . encode ( '.' ) , typeof jws . payload === 'string' ? encoder . encode ( jws . payload ) : jws . payload ) ;
const signature = decode$1 ( jws . signature ) ;
const verified = await verify ( alg , key , signature , data ) ;
if ( ! verified ) {
throw new JWSSignatureVerificationFailed ( ) ;
}
let payload ;
if ( b64 ) {
payload = decode$1 ( jws . payload ) ;
}
else if ( typeof jws . payload === 'string' ) {
payload = encoder . encode ( jws . payload ) ;
}
else {
payload = jws . payload ;
}
const result = { payload } ;
if ( jws . protected !== undefined ) {
result . protectedHeader = parsedProt ;
}
if ( jws . header !== undefined ) {
result . unprotectedHeader = jws . header ;
}
if ( resolvedKey ) {
return { ... result , key } ;
}
return result ;
}
async function compactVerify ( jws , key , options ) {
if ( jws instanceof Uint8Array ) {
jws = decoder . decode ( jws ) ;
}
if ( typeof jws !== 'string' ) {
throw new JWSInvalid ( 'Compact JWS must be a string or Uint8Array' ) ;
}
const { 0 : protectedHeader , 1 : payload , 2 : signature , length } = jws . split ( '.' ) ;
if ( length !== 3 ) {
throw new JWSInvalid ( 'Invalid Compact JWS' ) ;
}
const verified = await flattenedVerify ( { payload , protected : protectedHeader , signature } , key , options ) ;
const result = { payload : verified . payload , protectedHeader : verified . protectedHeader } ;
if ( typeof key === 'function' ) {
return { ... result , key : verified . key } ;
}
return result ;
}
const check = ( value , description ) => {
if ( typeof value !== 'string' || ! value ) {
throw new JWKInvalid ( ` ${ description } missing or invalid ` ) ;
}
} ;
async function calculateJwkThumbprint ( jwk , digestAlgorithm ) {
if ( ! isObject ( jwk ) ) {
throw new TypeError ( 'JWK must be an object' ) ;
}
digestAlgorithm !== null && digestAlgorithm !== void 0 ? digestAlgorithm : ( digestAlgorithm = 'sha256' ) ;
if ( digestAlgorithm !== 'sha256' &&
digestAlgorithm !== 'sha384' &&
digestAlgorithm !== 'sha512' ) {
throw new TypeError ( 'digestAlgorithm must one of "sha256", "sha384", or "sha512"' ) ;
}
let components ;
switch ( jwk . kty ) {
case 'EC' :
check ( jwk . crv , '"crv" (Curve) Parameter' ) ;
check ( jwk . x , '"x" (X Coordinate) Parameter' ) ;
check ( jwk . y , '"y" (Y Coordinate) Parameter' ) ;
components = { crv : jwk . crv , kty : jwk . kty , x : jwk . x , y : jwk . y } ;
break ;
case 'OKP' :
check ( jwk . crv , '"crv" (Subtype of Key Pair) Parameter' ) ;
check ( jwk . x , '"x" (Public Key) Parameter' ) ;
components = { crv : jwk . crv , kty : jwk . kty , x : jwk . x } ;
break ;
case 'RSA' :
check ( jwk . e , '"e" (Exponent) Parameter' ) ;
check ( jwk . n , '"n" (Modulus) Parameter' ) ;
components = { e : jwk . e , kty : jwk . kty , n : jwk . n } ;
break ;
case 'oct' :
check ( jwk . k , '"k" (Key Value) Parameter' ) ;
components = { k : jwk . k , kty : jwk . kty } ;
break ;
default :
throw new JOSENotSupported ( '"kty" (Key Type) Parameter missing or unsupported' ) ;
}
const data = encoder . encode ( JSON . stringify ( components ) ) ;
return encode ( await digest ( digestAlgorithm , data ) ) ;
}
const decode = decode$1 ;
function decodeProtectedHeader ( token ) {
let protectedB64u ;
if ( typeof token === 'string' ) {
const parts = token . split ( '.' ) ;
if ( parts . length === 3 || parts . length === 5 ) {
[ protectedB64u ] = parts ;
}
}
else if ( typeof token === 'object' && token ) {
if ( 'protected' in token ) {
protectedB64u = token . protected ;
}
else {
throw new TypeError ( 'Token does not contain a Protected Header' ) ;
}
}
try {
if ( typeof protectedB64u !== 'string' || ! protectedB64u ) {
throw new Error ( ) ;
}
const result = JSON . parse ( decoder . decode ( decode ( protectedB64u ) ) ) ;
if ( ! isObject ( result ) ) {
throw new Error ( ) ;
}
return result ;
}
catch ( _a ) {
throw new TypeError ( 'Invalid Token or Protected Header formatting' ) ;
}
}
var lib = { } ;
Object . defineProperty ( lib , '__esModule' , { value : true } ) ;
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
2023-07-13 02:41:31 -06:00
function parse$1 ( string , encoding , opts ) {
2023-07-09 04:05:21 -06:00
var _opts$out ;
if ( opts === void 0 ) {
opts = { } ;
}
// Build the character lookup table:
if ( ! encoding . codes ) {
encoding . codes = { } ;
for ( var i = 0 ; i < encoding . chars . length ; ++ i ) {
encoding . codes [ encoding . chars [ i ] ] = i ;
}
} // The string must have a whole number of bytes:
if ( ! opts . loose && string . length * encoding . bits & 7 ) {
throw new SyntaxError ( 'Invalid padding' ) ;
} // Count the padding bytes:
var end = string . length ;
while ( string [ end - 1 ] === '=' ) {
-- end ; // If we get a whole number of bytes, there is too much padding:
if ( ! opts . loose && ! ( ( string . length - end ) * encoding . bits & 7 ) ) {
throw new SyntaxError ( 'Invalid padding' ) ;
}
} // Allocate the output:
var out = new ( ( _opts$out = opts . out ) != null ? _opts$out : Uint8Array ) ( end * encoding . bits / 8 | 0 ) ; // Parse the data:
var bits = 0 ; // Number of bits currently in the buffer
var buffer = 0 ; // Bits waiting to be written out, MSB first
var written = 0 ; // Next byte to write
for ( var _i = 0 ; _i < end ; ++ _i ) {
// Read one character from the string:
var value = encoding . codes [ string [ _i ] ] ;
if ( value === undefined ) {
throw new SyntaxError ( 'Invalid character ' + string [ _i ] ) ;
} // Append the bits to the buffer:
buffer = buffer << encoding . bits | value ;
bits += encoding . bits ; // Write out some bits if the buffer has a byte's worth:
if ( bits >= 8 ) {
bits -= 8 ;
out [ written ++ ] = 0xff & buffer >> bits ;
}
} // Verify that we have received just enough bits:
if ( bits >= encoding . bits || 0xff & buffer << 8 - bits ) {
throw new SyntaxError ( 'Unexpected end of data' ) ;
}
return out ;
}
function stringify ( data , encoding , opts ) {
if ( opts === void 0 ) {
opts = { } ;
}
var _opts = opts ,
_opts$pad = _opts . pad ,
pad = _opts$pad === void 0 ? true : _opts$pad ;
var mask = ( 1 << encoding . bits ) - 1 ;
var out = '' ;
var bits = 0 ; // Number of bits currently in the buffer
var buffer = 0 ; // Bits waiting to be written out, MSB first
for ( var i = 0 ; i < data . length ; ++ i ) {
// Slurp data into the buffer:
buffer = buffer << 8 | 0xff & data [ i ] ;
bits += 8 ; // Write out as much as we can:
while ( bits > encoding . bits ) {
bits -= encoding . bits ;
out += encoding . chars [ mask & buffer >> bits ] ;
}
} // Partial character:
if ( bits ) {
out += encoding . chars [ mask & buffer << encoding . bits - bits ] ;
} // Add padding characters until we hit a byte boundary:
if ( pad ) {
while ( out . length * encoding . bits & 7 ) {
out += '=' ;
}
}
return out ;
}
/* eslint-disable @typescript-eslint/strict-boolean-expressions */
var base16Encoding = {
chars : '0123456789ABCDEF' ,
bits : 4
} ;
var base32Encoding = {
chars : 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567' ,
bits : 5
} ;
var base32HexEncoding = {
chars : '0123456789ABCDEFGHIJKLMNOPQRSTUV' ,
bits : 5
} ;
var base64Encoding = {
chars : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/' ,
bits : 6
} ;
var base64UrlEncoding = {
chars : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_' ,
bits : 6
} ;
var base16 = {
2023-07-13 02:41:31 -06:00
parse : function parse$1$1 ( string , opts ) {
return parse$1 ( string . toUpperCase ( ) , base16Encoding , opts ) ;
2023-07-09 04:05:21 -06:00
} ,
stringify : function stringify$1 ( data , opts ) {
return stringify ( data , base16Encoding , opts ) ;
}
} ;
var base32$1 = {
2023-07-13 02:41:31 -06:00
parse : function parse$1$1 ( string , opts ) {
2023-07-09 04:05:21 -06:00
if ( opts === void 0 ) {
opts = { } ;
}
2023-07-13 02:41:31 -06:00
return parse$1 ( opts . loose ? string . toUpperCase ( ) . replace ( /0/g , 'O' ) . replace ( /1/g , 'L' ) . replace ( /8/g , 'B' ) : string , base32Encoding , opts ) ;
2023-07-09 04:05:21 -06:00
} ,
stringify : function stringify$1 ( data , opts ) {
return stringify ( data , base32Encoding , opts ) ;
}
} ;
var base32hex = {
2023-07-13 02:41:31 -06:00
parse : function parse$1$1 ( string , opts ) {
return parse$1 ( string , base32HexEncoding , opts ) ;
2023-07-09 04:05:21 -06:00
} ,
stringify : function stringify$1 ( data , opts ) {
return stringify ( data , base32HexEncoding , opts ) ;
}
} ;
var base64 = {
2023-07-13 02:41:31 -06:00
parse : function parse$1$1 ( string , opts ) {
return parse$1 ( string , base64Encoding , opts ) ;
2023-07-09 04:05:21 -06:00
} ,
stringify : function stringify$1 ( data , opts ) {
return stringify ( data , base64Encoding , opts ) ;
}
} ;
var base64url$1 = {
2023-07-13 02:41:31 -06:00
parse : function parse$1$1 ( string , opts ) {
return parse$1 ( string , base64UrlEncoding , opts ) ;
2023-07-09 04:05:21 -06:00
} ,
stringify : function stringify$1 ( data , opts ) {
return stringify ( data , base64UrlEncoding , opts ) ;
}
} ;
var codec = {
2023-07-13 02:41:31 -06:00
parse : parse$1 ,
2023-07-09 04:05:21 -06:00
stringify : stringify
} ;
lib . base16 = base16 ;
lib . base32 = base32$1 ;
lib . base32hex = base32hex ;
lib . base64 = base64 ;
lib . base64url = base64url$1 ;
lib . codec = codec ;
// Generated by rollup-plugin-mjs-entry
lib . base16 ;
const base32 = lib . base32 ;
lib . base32hex ;
lib . base64 ;
const base64url = lib . base64url ;
lib . codec ;
/ *
Copyright 2023 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 SupportedCryptoAlg = [ 'EdDSA' , 'ES256' , 'ES256K' , 'ES384' , 'ES512' ] ;
/ * *
* Functions related to Ariadne Signature Profiles
* @ module asp
* /
/ * *
* Fetch a public key using Web Key Directory
* @ function
* @ param { string } uri - ASPE URI
* @ returns { Promise < Profile > }
* @ example
* const key = doip . aspe . fetchASPE ( 'aspe:domain.tld:1234567890' ) ;
* /
async function fetchASPE ( uri ) {
const re = /aspe:(.*):(.*)/ ;
if ( ! re . test ( uri ) ) {
throw new Error ( 'Invalid ASPE URI' )
}
const matches = uri . match ( re ) ;
const domainPart = matches [ 1 ] ;
const localPart = matches [ 2 ] . toUpperCase ( ) ;
const profileUrl = ` https:// ${ domainPart } /.well-known/aspe/id/ ${ localPart } ` ;
let profileJws ;
try {
profileJws = await axios$1 . get (
profileUrl ,
{
responseType : 'text'
}
)
. then ( ( /** @type {import('axios').AxiosResponse} */ response ) => {
if ( response . status === 200 ) {
return response
}
} )
. then ( ( /** @type {import('axios').AxiosResponse} */ response ) => response . data ) ;
} catch ( e ) {
throw new Error ( ` Error fetching Keybase key: ${ e . message } ` )
}
2023-07-13 02:41:31 -06:00
const profile = await parseProfileJws ( profileJws , uri ) ;
profile . publicKey . fetch . method = PublicKeyFetchMethod . ASPE ;
profile . publicKey . fetch . query = uri ;
profile . publicKey . fetch . resolvedUrl = profileUrl ;
return profile
2023-07-09 04:05:21 -06:00
}
/ * *
* Fetch a public key using Web Key Directory
* @ function
* @ param { string } profileJws - Compact - Serialized profile JWS
* @ param { string } uri - The ASPE URI associated with the profile
* @ returns { Promise < Profile > }
* @ example
* const key = doip . aspe . parseProfileJws ( '...' ) ;
* /
async function parseProfileJws ( profileJws , uri ) {
const matches = uri . match ( /aspe:(.*):(.*)/ ) ;
const localPart = matches [ 2 ] . toUpperCase ( ) ;
// Decode the headers
const protectedHeader = decodeProtectedHeader ( profileJws ) ;
// Extract the JWK
if ( ! SupportedCryptoAlg . includes ( protectedHeader . alg ) ) {
throw new Error ( 'Invalid profile JWS: wrong key algorithm' )
}
if ( ! protectedHeader . kid ) {
throw new Error ( 'Invalid profile JWS: missing key identifier' )
}
if ( ! protectedHeader . jwk ) {
throw new Error ( 'Invalid profile JWS: missing key' )
}
const publicKey = await importJWK ( protectedHeader . jwk , protectedHeader . alg ) ;
// Compute and verify the fingerprint
const fp = await computeJwkFingerprint ( protectedHeader . jwk ) ;
if ( fp !== protectedHeader . kid ) {
throw new Error ( 'Invalid profile JWS: wrong key' )
}
if ( localPart && fp !== localPart ) {
throw new Error ( 'Invalid profile JWS: wrong key' )
}
// Decode the payload
const { payload } = await compactVerify ( profileJws , publicKey ) ;
const payloadJson = JSON . parse ( new TextDecoder ( ) . decode ( payload ) ) ;
// Verify the payload
if ( ! ( Object . prototype . hasOwnProperty . call ( payloadJson , 'http://ariadne.id/type' ) && payloadJson [ 'http://ariadne.id/type' ] === 'profile' ) ) {
throw new Error ( 'Invalid profile JWS: JWS is not a profile' )
}
if ( ! ( Object . prototype . hasOwnProperty . call ( payloadJson , 'http://ariadne.id/version' ) && payloadJson [ 'http://ariadne.id/version' ] === 0 ) ) {
throw new Error ( 'Invalid profile JWS: profile version not supported' )
}
// Extract data from the payload
/** @type {string} */
const profileName = payloadJson [ 'http://ariadne.id/name' ] ;
/** @type {string} */
const profileDescription = payloadJson [ 'http://ariadne.id/description' ] ;
/** @type {string[]} */
const profileClaims = payloadJson [ 'http://ariadne.id/claims' ] ;
const profileClaimsParsed = profileClaims . map ( x => new Claim ( x , uri ) ) ;
const pe = new Persona ( profileName , profileClaimsParsed ) ;
if ( profileDescription ) {
pe . setDescription ( profileDescription ) ;
}
2023-07-13 02:41:31 -06:00
const profile = new Profile ( ProfileType . ASP , uri , [ pe ] ) ;
profile . publicKey . fingerprint = fp ;
profile . publicKey . encoding = PublicKeyEncoding . JWK ;
profile . publicKey . encodedKey = JSON . stringify ( protectedHeader . jwk ) ;
profile . publicKey . key = protectedHeader . jwk ;
2023-07-09 04:05:21 -06:00
2023-07-13 02:41:31 -06:00
switch ( protectedHeader . alg ) {
case 'ES256' :
profile . publicKey . keyType = PublicKeyType . ES256 ;
break
case 'EdDSA' :
profile . publicKey . keyType = PublicKeyType . EDDSA ;
break
default :
profile . publicKey . keyType = PublicKeyType . UNKNOWN ;
break
}
return profile
2023-07-09 04:05:21 -06:00
}
/ * *
* Compute the fingerprint for JWK keys
* @ function
* @ param { import ( 'jose' ) . JWK } key
* @ returns { Promise < string > }
* /
async function computeJwkFingerprint ( key ) {
const thumbprint = await calculateJwkThumbprint ( key , 'sha512' ) ;
const fingerprintBytes = base64url . parse ( thumbprint , { loose : true } ) . slice ( 0 , 16 ) ;
const fingerprint = base32 . stringify ( fingerprintBytes , { pad : false } ) ;
return fingerprint
}
var asp = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
computeJwkFingerprint : computeJwkFingerprint ,
fetchASPE : fetchASPE ,
parseProfileJws : parseProfileJws
} ) ;
/ *
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
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 .
* /
/ * *
* @ module signatures
* /
/ * *
2023-07-13 02:41:31 -06:00
* Extract the profile from a signature and fetch the associated key
2023-07-09 04:05:21 -06:00
* @ async
2023-07-13 02:41:31 -06:00
* @ param { string } signature - The plaintext signature to parse
* @ returns { Promise < import ( './profile.js' ) . Profile > }
2023-07-09 04:05:21 -06:00
* /
2023-07-13 02:41:31 -06:00
async function parse ( signature ) {
2023-07-09 04:05:21 -06:00
/** @type {import('openpgp').CleartextMessage} */
let sigData ;
// Read the signature
try {
sigData = await openpgp$1 . readCleartextMessage ( {
cleartextMessage : signature
} ) ;
} catch ( e ) {
throw new Error ( ` Signature could not be read ( ${ e . message } ) ` )
}
// @ts-ignore
const issuerKeyID = sigData . signature . packets [ 0 ] . issuerKeyID . toHex ( ) ;
// @ts-ignore
const signersUserID = sigData . signature . packets [ 0 ] . signersUserID ;
const preferredKeyServer =
// @ts-ignore
sigData . signature . packets [ 0 ] . preferredKeyServer ||
'https://keys.openpgp.org/' ;
const text = sigData . getText ( ) ;
const sigKeys = [ ] ;
2023-07-13 02:41:31 -06:00
const claims = [ ] ;
2023-07-09 04:05:21 -06:00
text . split ( '\n' ) . forEach ( ( line , i ) => {
const match = line . match ( /^([a-zA-Z0-9]*)=(.*)$/i ) ;
if ( ! match ) {
return
}
switch ( match [ 1 ] . toLowerCase ( ) ) {
case 'key' :
sigKeys . push ( match [ 2 ] ) ;
break
case 'proof' :
2023-07-13 02:41:31 -06:00
claims . push ( new Claim ( match [ 2 ] ) ) ;
2023-07-09 04:05:21 -06:00
break
}
} ) ;
2023-07-13 02:41:31 -06:00
const obtainedKey = {
query : null ,
data : null ,
method : null
} ;
// Try key identifier found in the signature
2023-07-09 04:05:21 -06:00
if ( sigKeys . length > 0 ) {
try {
2023-07-13 02:41:31 -06:00
obtainedKey . query = sigKeys [ 0 ] ;
/** @type {import('openpgp').PublicKey} */
obtainedKey . data = ( await fetchURI ( obtainedKey . query ) ) . publicKey . key ;
obtainedKey . method = obtainedKey . query . split ( ':' ) [ 0 ] ;
2023-07-09 04:05:21 -06:00
} catch ( e ) { }
}
// Try WKD
2023-07-13 02:41:31 -06:00
if ( ! obtainedKey . data && signersUserID ) {
2023-07-09 04:05:21 -06:00
try {
2023-07-13 02:41:31 -06:00
obtainedKey . query = signersUserID ;
obtainedKey . data = ( await fetchURI ( ` wkd: ${ signersUserID } ` ) ) . publicKey . key ;
obtainedKey . method = 'wkd' ;
2023-07-09 04:05:21 -06:00
} catch ( e ) { }
}
// Try HKP
2023-07-13 02:41:31 -06:00
if ( ! obtainedKey . data ) {
2023-07-09 04:05:21 -06:00
try {
const match = preferredKeyServer . match ( /^(.*:\/\/)?([^/]*)(?:\/)?$/i ) ;
2023-07-13 02:41:31 -06:00
obtainedKey . query = issuerKeyID || signersUserID ;
obtainedKey . data = ( await fetchURI ( ` hkp: ${ match [ 2 ] } : ${ obtainedKey . query } ` ) ) . publicKey . key ;
obtainedKey . method = 'hkp' ;
2023-07-09 04:05:21 -06:00
} catch ( e ) {
throw new Error ( 'Public key not found' )
}
}
2023-07-13 02:41:31 -06:00
const primaryUserData = await obtainedKey . data . getPrimaryUser ( ) ;
const fingerprint = obtainedKey . data . getFingerprint ( ) ;
2023-07-09 04:05:21 -06:00
// Verify the signature
const verificationResult = await openpgp$1 . verify ( {
// @ts-ignore
message : sigData ,
2023-07-13 02:41:31 -06:00
verificationKeys : obtainedKey . data
2023-07-09 04:05:21 -06:00
} ) ;
const { verified } = verificationResult . signatures [ 0 ] ;
try {
await verified ;
} catch ( e ) {
throw new Error ( ` Signature could not be verified ( ${ e . message } ) ` )
}
2023-07-13 02:41:31 -06:00
// Build the persona
const persona = new Persona ( primaryUserData . user . userID . name , [ ] ) ;
persona . setIdentifier ( primaryUserData . user . userID . userID ) ;
persona . setDescription ( primaryUserData . user . userID . comment || null ) ;
persona . setEmailAddress ( primaryUserData . user . userID . email || null ) ;
persona . claims = claims
. map (
( { value } ) =>
new Claim ( new TextDecoder ( ) . decode ( value ) , ` openpgp4fpr: ${ fingerprint } ` )
) ;
2023-07-09 04:05:21 -06:00
2023-07-13 02:41:31 -06:00
const profile = new Profile ( ProfileType . OPENPGP , ` openpgp4fpr: ${ fingerprint } ` , [ persona ] ) ;
2023-07-09 04:05:21 -06:00
2023-07-13 02:41:31 -06:00
profile . publicKey . keyType = PublicKeyType . OPENPGP ;
profile . publicKey . encoding = PublicKeyEncoding . ARMORED _PGP ;
profile . publicKey . encodedKey = obtainedKey . data . armor ( ) ;
profile . publicKey . key = obtainedKey . data ;
profile . publicKey . fetch . method = obtainedKey . method ;
profile . publicKey . fetch . query = obtainedKey . query ;
2023-07-09 04:05:21 -06:00
2023-07-13 02:41:31 -06:00
return profile
2023-07-09 04:05:21 -06:00
}
var signatures = /*#__PURE__*/ Object . freeze ( {
_ _proto _ _ : null ,
2023-07-13 02:41:31 -06:00
parse : parse
2023-07-09 04:05:21 -06:00
} ) ;
exports . fetcher = fetcher _ _namespace ;
exports . Claim = Claim ;
exports . Persona = Persona ;
exports . Profile = Profile ;
exports . ServiceProvider = ServiceProvider ;
exports . ServiceProviderDefinitions = index ;
exports . asp = asp ;
exports . defaults = defaults$3 ;
exports . enums = enums ;
exports . openpgp = openpgp ;
exports . proofs = proofs ;
exports . signatures = signatures ;
exports . utils = utils$9 ;
exports . verifications = verifications ;
return exports ;
2023-07-08 00:36:57 -06:00
2023-09-18 09:46:54 -06:00
} ) ( { } , openpgp , doipFetchers ) ;