@windingtree/org.id-resolver
Advanced tools
Comparing version 0.4.4 to 1.0.0
module.exports = { | ||
"extends": "eslint:recommended", | ||
"env": { | ||
"es6": true, | ||
"browser": true, | ||
"node": true, | ||
"mocha": true, | ||
"jest": true | ||
'extends': 'eslint:recommended', | ||
'env': { | ||
'es6': true, | ||
'browser': true, | ||
'node': true, | ||
'mocha': true, | ||
'jest': true | ||
}, | ||
"globals": { | ||
"artifacts": false, | ||
"contract": false, | ||
"assert": false, | ||
"web3": false | ||
'globals': { | ||
'artifacts': false, | ||
'contract': false, | ||
'assert': false, | ||
'web3': false | ||
}, | ||
"parserOptions": { | ||
"ecmaVersion": 8 | ||
'parserOptions': { | ||
'ecmaVersion': 9 | ||
}, | ||
"rules": { | ||
'rules': { | ||
// Strict mode | ||
"strict": 0, | ||
'strict': 0, | ||
// Code style | ||
"indent": ["error", 4, { | ||
"SwitchCase": 1 | ||
'indent': ['error', 4, { | ||
'SwitchCase': 1 | ||
}], | ||
"quotes": [2, "single"], | ||
"semi": ["error", "always"], | ||
"space-before-function-paren": 0, | ||
"no-use-before-define": 0, | ||
"eqeqeq": [2, "smart"], | ||
"dot-notation": [2, { | ||
"allowKeywords": true, | ||
"allowPattern": "" | ||
'quotes': [2, 'single'], | ||
'semi': ['error', 'always'], | ||
'space-before-function-paren': ['error', 'always'], | ||
'no-use-before-define': 0, | ||
'eqeqeq': [2, 'smart'], | ||
'dot-notation': [2, { | ||
'allowKeywords': true, | ||
'allowPattern': '' | ||
}], | ||
"no-redeclare": [2, { | ||
"builtinGlobals": true | ||
'no-redeclare': [2, { | ||
'builtinGlobals': true | ||
}], | ||
"no-trailing-spaces": [2, { | ||
"skipBlankLines": true | ||
'no-trailing-spaces': [2, { | ||
'skipBlankLines': true | ||
}], | ||
"eol-last": 1, | ||
"comma-spacing": [2, { | ||
"before": false, | ||
"after": true | ||
'eol-last': 1, | ||
'comma-spacing': [2, { | ||
'before': false, | ||
'after': true | ||
}], | ||
"camelcase": [2, { | ||
"properties": "always" | ||
}], | ||
"no-mixed-spaces-and-tabs": [2, "smart-tabs"], | ||
"comma-dangle": [1, "only-multiline"], | ||
"no-dupe-args": 2, | ||
"no-dupe-keys": 2, | ||
"no-debugger": 0, | ||
"no-undef": 2, | ||
"one-var": [0], | ||
"object-curly-spacing": [2, "always"], | ||
"generator-star-spacing": ["error", "before"], | ||
"padded-blocks": 0, | ||
"no-unused-expressions": 0, | ||
"arrow-body-style": 0, | ||
"no-extra-semi": 0 | ||
'camelcase': 0, | ||
'no-mixed-spaces-and-tabs': [2, 'smart-tabs'], | ||
'comma-dangle': [1, 'only-multiline'], | ||
'no-dupe-args': 2, | ||
'no-dupe-keys': 2, | ||
'no-debugger': 0, | ||
'no-undef': 2, | ||
'one-var': [0], | ||
'object-curly-spacing': [2, 'always'], | ||
'generator-star-spacing': ['error', 'before'], | ||
'padded-blocks': 0, | ||
'no-unused-expressions': 0, | ||
'arrow-body-style': 0, | ||
'no-extra-semi': 0 | ||
} | ||
}; |
@@ -5,2 +5,2 @@ "use strict";require("core-js/modules/es6.promise");require("core-js/modules/es6.object.to-string");require("regenerator-runtime/runtime");function asyncGeneratorStep(gen,resolve,reject,_next,_throw,key,arg){try{var info=gen[key](arg);var value=info.value}catch(error){reject(error);return}if(info.done){resolve(value)}else{Promise.resolve(value).then(_next,_throw)}}function _asyncToGenerator(fn){return function(){var self=this,args=arguments;return new Promise(function(resolve,reject){var gen=fn.apply(self,args);function _next(value){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"next",value)}function _throw(err){asyncGeneratorStep(gen,resolve,reject,_next,_throw,"throw",err)}_next(undefined)})}}var axios=require("axios");// Configuration of the HTTP fetching method | ||
cancelToken:source.token});case 4:response=_context.sent;clearTimeout(timeout);return _context.abrupt("return",response.data);case 7:case"end":return _context.stop();}}},_callee)}));function fetch(_x){return _fetch.apply(this,arguments)}return fetch}()}; | ||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9odHRwLmpzIl0sIm5hbWVzIjpbImF4aW9zIiwicmVxdWlyZSIsIm1vZHVsZSIsImV4cG9ydHMiLCJuYW1lIiwicGF0dGVybiIsImZldGNoIiwidXJpIiwic291cmNlIiwiQ2FuY2VsVG9rZW4iLCJ0aW1lb3V0Iiwic2V0VGltZW91dCIsImNhbmNlbCIsImdldCIsInRyYW5zZm9ybVJlc3BvbnNlIiwiZGF0YSIsImNhbmNlbFRva2VuIiwidG9rZW4iLCJyZXNwb25zZSIsImNsZWFyVGltZW91dCJdLCJtYXBwaW5ncyI6InFzQkFBQSxHQUFNQSxDQUFBQSxLQUFLLENBQUdDLE9BQU8sQ0FBQyxPQUFELENBQXJCLENBRUE7QUFDQUMsTUFBTSxDQUFDQyxPQUFQLENBQWlCLENBQ2JDLElBQUksQ0FBRSxNQURPLENBRWJDLE9BQU8sQ0FBRSxnQkFGSSxDQUdiQyxLQUFLLDhFQUFFLGlCQUFNQyxHQUFOLDZJQUNHQyxNQURILENBQ1lSLEtBQUssQ0FBQ1MsV0FBTixDQUFrQkQsTUFBbEIsRUFEWixDQUVHRSxPQUZILENBRWFDLFVBQVUsQ0FBQyxpQkFBTUgsQ0FBQUEsTUFBTSxDQUFDSSxNQUFQLHlDQUNJTCxHQURKLEVBQU4sQ0FBRCxDQUV2QixJQUZ1QixDQUZ2QixDQUlNO0FBSk4sc0JBS29CUCxDQUFBQSxLQUFLLENBQUNhLEdBQU4sQ0FBVU4sR0FBVixDQUFlLENBQ2xDTyxpQkFBaUIsQ0FBRSxDQUFDLFNBQUNDLElBQUQsQ0FBVSxDQUFFLE1BQU9BLENBQUFBLElBQU8sQ0FBM0IsQ0FEZSxDQUNlO0FBQ2pEQyxXQUFXLENBQUVSLE1BQU0sQ0FBQ1MsS0FGYyxDQUFmLENBTHBCLFFBS0dDLFFBTEgsZUFTSEMsWUFBWSxDQUFDVCxPQUFELENBQVosQ0FURyxnQ0FVSVEsUUFBUSxDQUFDSCxJQVZiLHVEQUFGLHlFQUhRLENBQWpCIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgYXhpb3MgPSByZXF1aXJlKCdheGlvcycpO1xuXG4vLyBDb25maWd1cmF0aW9uIG9mIHRoZSBIVFRQIGZldGNoaW5nIG1ldGhvZFxubW9kdWxlLmV4cG9ydHMgPSB7XG4gICAgbmFtZTogJ2h0dHAnLFxuICAgIHBhdHRlcm46ICdeaHR0cDp8Xmh0dHBzOicsXG4gICAgZmV0Y2g6IGFzeW5jIHVyaSA9PiB7XG4gICAgICAgIGNvbnN0IHNvdXJjZSA9IGF4aW9zLkNhbmNlbFRva2VuLnNvdXJjZSgpO1xuICAgICAgICBjb25zdCB0aW1lb3V0ID0gc2V0VGltZW91dCgoKSA9PiBzb3VyY2UuY2FuY2VsKFxuICAgICAgICAgICAgYENhbm5vdCBjb25uZWN0IHRvIHRoZSBzb3VyY2U6ICR7dXJpfWBcbiAgICAgICAgKSwgNTAwMCk7Ly8gY29ubmVjdGlvbiB0aW1lb3V0XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgYXhpb3MuZ2V0KHVyaSwge1xuICAgICAgICAgICAgdHJhbnNmb3JtUmVzcG9uc2U6IFsoZGF0YSkgPT4geyByZXR1cm4gZGF0YTsgfV0sIC8vIERvIG5vdCBjb252ZXJ0IEpTT04gdG8gb2JqZWN0XG4gICAgICAgICAgICBjYW5jZWxUb2tlbjogc291cmNlLnRva2VuXG4gICAgICAgIH0pO1xuICAgICAgICBjbGVhclRpbWVvdXQodGltZW91dCk7XG4gICAgICAgIHJldHVybiByZXNwb25zZS5kYXRhO1xuICAgIH1cbn07XG4iXX0= | ||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uL3NyYy9odHRwLmpzIl0sIm5hbWVzIjpbImF4aW9zIiwicmVxdWlyZSIsIm1vZHVsZSIsImV4cG9ydHMiLCJuYW1lIiwicGF0dGVybiIsImZldGNoIiwidXJpIiwic291cmNlIiwiQ2FuY2VsVG9rZW4iLCJ0aW1lb3V0Iiwic2V0VGltZW91dCIsImNhbmNlbCIsImdldCIsInRyYW5zZm9ybVJlc3BvbnNlIiwiZGF0YSIsImNhbmNlbFRva2VuIiwidG9rZW4iLCJyZXNwb25zZSIsImNsZWFyVGltZW91dCJdLCJtYXBwaW5ncyI6InFzQkFBQSxHQUFNQSxDQUFBQSxLQUFLLENBQUdDLE9BQU8sQ0FBQyxPQUFELENBQXJCLENBRUE7QUFDQUMsTUFBTSxDQUFDQyxPQUFQLENBQWlCLENBQ2JDLElBQUksQ0FBRSxNQURPLENBRWJDLE9BQU8sQ0FBRSxnQkFGSSxDQUdiQyxLQUFLLDhFQUFFLGlCQUFNQyxHQUFOLDZJQUNHQyxNQURILENBQ1lSLEtBQUssQ0FBQ1MsV0FBTixDQUFrQkQsTUFBbEIsRUFEWixDQUVHRSxPQUZILENBRWFDLFVBQVUsQ0FBQyxpQkFBTUgsQ0FBQUEsTUFBTSxDQUFDSSxNQUFQLHlDQUNJTCxHQURKLEVBQU4sQ0FBRCxDQUV2QixJQUZ1QixDQUZ2QixDQUlNO0FBSk4sc0JBS29CUCxDQUFBQSxLQUFLLENBQUNhLEdBQU4sQ0FBVU4sR0FBVixDQUFlLENBQ2xDTyxpQkFBaUIsQ0FBRSxDQUFDLFNBQUFDLElBQUksUUFBSUEsQ0FBQUEsSUFBSixDQUFMLENBRGUsQ0FDQztBQUNuQ0MsV0FBVyxDQUFFUixNQUFNLENBQUNTLEtBRmMsQ0FBZixDQUxwQixRQUtHQyxRQUxILGVBU0hDLFlBQVksQ0FBQ1QsT0FBRCxDQUFaLENBVEcsZ0NBVUlRLFFBQVEsQ0FBQ0gsSUFWYix1REFBRix5RUFIUSxDQUFqQiIsInNvdXJjZXNDb250ZW50IjpbImNvbnN0IGF4aW9zID0gcmVxdWlyZSgnYXhpb3MnKTtcblxuLy8gQ29uZmlndXJhdGlvbiBvZiB0aGUgSFRUUCBmZXRjaGluZyBtZXRob2Rcbm1vZHVsZS5leHBvcnRzID0ge1xuICAgIG5hbWU6ICdodHRwJyxcbiAgICBwYXR0ZXJuOiAnXmh0dHA6fF5odHRwczonLFxuICAgIGZldGNoOiBhc3luYyB1cmkgPT4ge1xuICAgICAgICBjb25zdCBzb3VyY2UgPSBheGlvcy5DYW5jZWxUb2tlbi5zb3VyY2UoKTtcbiAgICAgICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4gc291cmNlLmNhbmNlbChcbiAgICAgICAgICAgIGBDYW5ub3QgY29ubmVjdCB0byB0aGUgc291cmNlOiAke3VyaX1gXG4gICAgICAgICksIDUwMDApOy8vIGNvbm5lY3Rpb24gdGltZW91dFxuICAgICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IGF4aW9zLmdldCh1cmksIHtcbiAgICAgICAgICAgIHRyYW5zZm9ybVJlc3BvbnNlOiBbZGF0YSA9PiBkYXRhXSwgLy8gRG8gbm90IGNvbnZlcnQgSlNPTiB0byBvYmplY3RcbiAgICAgICAgICAgIGNhbmNlbFRva2VuOiBzb3VyY2UudG9rZW5cbiAgICAgICAgfSk7XG4gICAgICAgIGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgICAgICAgcmV0dXJuIHJlc3BvbnNlLmRhdGE7XG4gICAgfVxufTtcbiJdfQ== |
@@ -1,2 +0,2 @@ | ||
"use strict";require("core-js/modules/es6.regexp.constructor");require("core-js/modules/es7.array.includes");require("core-js/modules/es6.string.includes");require("core-js/modules/es6.regexp.split");require("core-js/modules/es6.object.keys");require("core-js/modules/es7.symbol.async-iterator");require("core-js/modules/es6.symbol");require("core-js/modules/web.dom.iterable");require("core-js/modules/es6.array.iterator");require("core-js/modules/es6.string.iterator");require("core-js/modules/es6.map");require("core-js/modules/es6.reflect.construct");require("core-js/modules/es6.regexp.to-string");require("core-js/modules/es6.object.to-string");require("core-js/modules/es6.object.set-prototype-of");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 _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function")}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,writable:true,configurable:true}});if(superClass)_setPrototypeOf(subClass,superClass)}function _createSuper(Derived){var hasNativeReflectConstruct=_isNativeReflectConstruct();return function(){var Super=_getPrototypeOf(Derived),result;if(hasNativeReflectConstruct){var NewTarget=_getPrototypeOf(this).constructor;result=Reflect.construct(Super,arguments,NewTarget)}else{result=Super.apply(this,arguments)}return _possibleConstructorReturn(this,result)}}function _possibleConstructorReturn(self,call){if(call&&(_typeof(call)==="object"||typeof call==="function")){return call}return _assertThisInitialized(self)}function _assertThisInitialized(self){if(self===void 0){throw new ReferenceError("this hasn't been initialised - super() hasn't been called")}return self}function _wrapNativeSuper(Class){var _cache=typeof Map==="function"?new Map:undefined;_wrapNativeSuper=function _wrapNativeSuper(Class){if(Class===null||!_isNativeFunction(Class))return Class;if(typeof Class!=="function"){throw new TypeError("Super expression must either be null or a function")}if(typeof _cache!=="undefined"){if(_cache.has(Class))return _cache.get(Class);_cache.set(Class,Wrapper)}function Wrapper(){return _construct(Class,arguments,_getPrototypeOf(this).constructor)}Wrapper.prototype=Object.create(Class.prototype,{constructor:{value:Wrapper,enumerable:false,writable:true,configurable:true}});return _setPrototypeOf(Wrapper,Class)};return _wrapNativeSuper(Class)}function _construct(Parent,args,Class){if(_isNativeReflectConstruct()){_construct=Reflect.construct}else{_construct=function _construct(Parent,args,Class){var a=[null];a.push.apply(a,args);var Constructor=Function.bind.apply(Parent,a);var instance=new Constructor;if(Class)_setPrototypeOf(instance,Class.prototype);return instance}}return _construct.apply(null,arguments)}function _isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{Date.prototype.toString.call(Reflect.construct(Date,[],function(){}));return true}catch(e){return false}}function _isNativeFunction(fn){return Function.toString.call(fn).indexOf("[native code]")!==-1}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf||function _setPrototypeOf(o,p){o.__proto__=p;return o};return _setPrototypeOf(o,p)}function _getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf:function _getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o)};return _getPrototypeOf(o)}var _require=require("web3"),web3utils=_require.utils;/** | ||
"use strict";require("core-js/modules/es6.regexp.constructor");require("core-js/modules/es7.array.includes");require("core-js/modules/es6.string.includes");require("core-js/modules/es6.regexp.split");require("core-js/modules/es6.object.keys");require("core-js/modules/es7.symbol.async-iterator");require("core-js/modules/es6.symbol");require("core-js/modules/web.dom.iterable");require("core-js/modules/es6.array.iterator");require("core-js/modules/es6.string.iterator");require("core-js/modules/es6.map");require("core-js/modules/es6.reflect.construct");require("core-js/modules/es6.regexp.to-string");require("core-js/modules/es6.object.to-string");require("core-js/modules/es6.object.set-prototype-of");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 _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}function _inherits(subClass,superClass){if(typeof superClass!=="function"&&superClass!==null){throw new TypeError("Super expression must either be null or a function")}subClass.prototype=Object.create(superClass&&superClass.prototype,{constructor:{value:subClass,writable:true,configurable:true}});if(superClass)_setPrototypeOf(subClass,superClass)}function _createSuper(Derived){var hasNativeReflectConstruct=_isNativeReflectConstruct();return function _createSuperInternal(){var Super=_getPrototypeOf(Derived),result;if(hasNativeReflectConstruct){var NewTarget=_getPrototypeOf(this).constructor;result=Reflect.construct(Super,arguments,NewTarget)}else{result=Super.apply(this,arguments)}return _possibleConstructorReturn(this,result)}}function _possibleConstructorReturn(self,call){if(call&&(_typeof(call)==="object"||typeof call==="function")){return call}return _assertThisInitialized(self)}function _assertThisInitialized(self){if(self===void 0){throw new ReferenceError("this hasn't been initialised - super() hasn't been called")}return self}function _wrapNativeSuper(Class){var _cache=typeof Map==="function"?new Map:undefined;_wrapNativeSuper=function _wrapNativeSuper(Class){if(Class===null||!_isNativeFunction(Class))return Class;if(typeof Class!=="function"){throw new TypeError("Super expression must either be null or a function")}if(typeof _cache!=="undefined"){if(_cache.has(Class))return _cache.get(Class);_cache.set(Class,Wrapper)}function Wrapper(){return _construct(Class,arguments,_getPrototypeOf(this).constructor)}Wrapper.prototype=Object.create(Class.prototype,{constructor:{value:Wrapper,enumerable:false,writable:true,configurable:true}});return _setPrototypeOf(Wrapper,Class)};return _wrapNativeSuper(Class)}function _construct(Parent,args,Class){if(_isNativeReflectConstruct()){_construct=Reflect.construct}else{_construct=function _construct(Parent,args,Class){var a=[null];a.push.apply(a,args);var Constructor=Function.bind.apply(Parent,a);var instance=new Constructor;if(Class)_setPrototypeOf(instance,Class.prototype);return instance}}return _construct.apply(null,arguments)}function _isNativeReflectConstruct(){if(typeof Reflect==="undefined"||!Reflect.construct)return false;if(Reflect.construct.sham)return false;if(typeof Proxy==="function")return true;try{Date.prototype.toString.call(Reflect.construct(Date,[],function(){}));return true}catch(e){return false}}function _isNativeFunction(fn){return Function.toString.call(fn).indexOf("[native code]")!==-1}function _setPrototypeOf(o,p){_setPrototypeOf=Object.setPrototypeOf||function _setPrototypeOf(o,p){o.__proto__=p;return o};return _setPrototypeOf(o,p)}function _getPrototypeOf(o){_getPrototypeOf=Object.setPrototypeOf?Object.getPrototypeOf:function _getPrototypeOf(o){return o.__proto__||Object.getPrototypeOf(o)};return _getPrototypeOf(o)}var _require=require("web3"),web3utils=_require.utils;/** | ||
* ExpectError class | ||
@@ -20,2 +20,2 @@ * @class ExpectError | ||
if(_typeof(value)!==model[key].type&&(model[key].required===true||model[key].required===undefined)){throw new ExpectError("The \"".concat(key,"\" property value has a wrong type: ").concat(_typeof(value)),{expected:model[key].type,key:key,value:value})}}}};module.exports.all=all; | ||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9leHBlY3QuanMiXSwibmFtZXMiOlsicmVxdWlyZSIsIndlYjN1dGlscyIsInV0aWxzIiwiRXhwZWN0RXJyb3IiLCJtZXNzYWdlIiwiYXJncyIsIkVycm9yIiwibW9kdWxlIiwiZXhwb3J0cyIsImFsbCIsIm9wdGlvbnMiLCJtb2RlbCIsIk9iamVjdCIsImtleXMiLCJsZW5ndGgiLCJrZXkiLCJ0eXBlIiwidmFsdWUiLCJzcGxpdCIsInJlZHVjZSIsImFjYyIsInBhcnQiLCJ1bmRlZmluZWQiLCJyZXF1aXJlZCIsImV4cGVjdGVkIiwidmFsdWVzIiwiQXJyYXkiLCJpc0FycmF5IiwiaW5jbHVkZXMiLCJTdHJpbmciLCJSZWdFeHAiLCJ0ZXN0IiwiaXNCTiIsInByb3ZpZGVyIiwibWVtYmVyVmFsdWUiXSwibWFwcGluZ3MiOiJrNkhBQTZCQSxPQUFPLENBQUMsTUFBRCxDLENBQXJCQyxTLFVBQVBDLEssQ0FFUjs7OztNQUtNQyxDQUFBQSxXLGtHQUVGOzs7O09BS0Esc0JBQWdELGNBQXBDQyxDQUFBQSxPQUFvQywyREFBMUIsZUFBMEIsbUNBQUU7QUFDOUMsdUJBQU1BLE9BQU4sRUFENEMsOEJBQU5DLElBQU0scURBQU5BLElBQU0seUJBRTVDLE1BQUtBLElBQUwsQ0FBWUEsSUFBWixDQUY0QyxZQUcvQyxDLGtEQVZxQkMsSyxHQVd6QixDQUNEQyxNQUFNLENBQUNDLE9BQVAsQ0FBZUwsV0FBZixDQUE2QkEsV0FBN0IsQ0FFQTs7OztHQUtBLEdBQU1NLENBQUFBLEdBQUcsQ0FBRyxRQUFOQSxDQUFBQSxHQUFNLEVBQThCLElBQTdCQyxDQUFBQSxPQUE2QiwyREFBbkIsRUFBbUIsSUFBZkMsQ0FBQUEsS0FBZSwyREFBUCxFQUFPLENBRXRDLEdBQUksUUFBT0QsT0FBUCxJQUFtQixRQUFuQixFQUErQkUsTUFBTSxDQUFDQyxJQUFQLENBQVlILE9BQVosRUFBcUJJLE1BQXJCLEdBQWdDLENBQW5FLENBQXNFLENBRWxFLEtBQU0sSUFB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Q0FBTCxDQUFXQyxJQUE1QixHQUNDTCxLQUFLLENBQUNJLEdBQUQsQ0FBTCxDQUFXUSxRQUFYLEdBQXdCLElBQXhCLEVBQWdDWixLQUFLLENBQUNJLEdBQUQsQ0FBTCxDQUFXUSxRQUFYLEdBQXdCRCxTQUR6RCxDQUFKLENBQ3lFLENBRXJFLEtBQU0sSUFBSW5CLENBQUFBLFdBQUosaUJBQ01ZLEdBRE4sd0RBQ3NERSxLQUR0RCxHQUVGLENBQ0lPLFFBQVEsQ0FBRWIsS0FBSyxDQUFDSSxHQUFELENBQUwsQ0FBV0MsSUFEekIsQ0FFSUQsR0FBRyxDQUFIQSxHQUZKLENBR0lFLEtBQUssQ0FBTEEsS0FISixDQUZFLENBUVQsQ0EzSVQsQ0E2SUgsQ0FDSixDQWxMRCxDQW1MQVYsTUFBTSxDQUFDQyxPQUFQLENBQWVDLEdBQWYsQ0FBcUJBLEdBQXJCIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgeyB1dGlsczogd2ViM3V0aWxzIH0gPSByZXF1aXJlKCd3ZWIzJyk7XG5cbi8qKlxuICogRXhwZWN0RXJyb3IgY2xhc3NcbiAqIEBjbGFzcyBFeHBlY3RFcnJvclxuICogQGV4dGVuZHMge0Vycm9yfVxuICovXG5jbGFzcyBFeHBlY3RFcnJvciBleHRlbmRzIEVycm9yIHtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgRXhwZWN0RXJyb3IuXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICAgKiBAbWVtYmVyb2YgRXhwZWN0RXJyb3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlID0gJ1Vua25vd24gZXJyb3InLCAuLi5hcmdzKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgc3BhY2UtYmVmb3JlLWZ1bmN0aW9uLXBhcmVuXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgICB0aGlzLmFyZ3MgPSBhcmdzO1xuICAgIH1cbn07XG5tb2R1bGUuZXhwb3J0cy5FeHBlY3RFcnJvciA9IEV4cGVjdEVycm9yO1xuXG4vKipcbiAqIEVuc3VyaW5nIGV4cGVjdGVkIHBhcmFtZXRlcnMgaGVscGVyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHBhcmFtIHtPYmplY3R9IG1vZGVsXG4gKi9cbmNvbnN0IGFsbCA9IChvcHRpb25zID0ge30sIG1vZGVsID0ge30pID0+IHtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcgfHwgT2JqZWN0LmtleXMob3B0aW9ucykubGVuZ3RoID09PSAwKSB7XG5cbiAgICAgICAgdGhyb3cgbmV3IEV4cGVjdEVycm9yKCdPcHRpb25zIGZvciBcImV4cGVjdC5hbGxcIiBtdXN0IGJlIGFuIG9iamVjdCcpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbW9kZWwgIT09ICdvYmplY3QnIHx8IE9iamVjdC5rZXlzKG1vZGVsKS5sZW5ndGggPT09IDApIHtcblxuICAgICAgICB0aHJvdyBuZXcgRXhwZWN0RXJyb3IoJ01vZGVsIGZvciBcImV4cGVjdC5hbGxcIiBtdXN0IGJlIGFuIG9iamVjdCcpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKG1vZGVsKSkge1xuXG4gICAgICAgIGlmICghbW9kZWxba2V5XS50eXBlKSB7XG5cbiAgICAgICAgICAgIHRocm93IG5ldyBFeHBlY3RFcnJvcignTW9kZWwgcHJvcGVydHkgbXVzdCBoYXZlIGEgXCJ0eXBlXCIgZGVmaW5lZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdmFsdWUgPSBrZXkuc3BsaXQoJy4nKS5yZWR1Y2UoKGFjYywgcGFydCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGFjYyAmJiBhY2NbcGFydF0gIT09IHVuZGVmaW5lZCA/IGFjY1twYXJ0XSA6IG51bGw7XG4gICAgICAgIH0sIG9wdGlvbnMpO1xuXG4gICAgICAgIGlmIChvcHRpb25zW2tleV0gPT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgKG1vZGVsW2tleV0ucmVxdWlyZWQgPT09IHRydWUgfHwgbW9kZWxba2V5XS5yZXF1aXJlZCA9PT0gdW5kZWZpbmVkKSkge1xuXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXhwZWN0RXJyb3IoXG4gICAgICAgICAgICAgICAgYFRoZSBcIiR7a2V5fVwiIHByb3BlcnR5IG5vdCBmb3VuZGAsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogbW9kZWxba2V5XS50eXBlLFxuICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAobW9kZWxba2V5XS50eXBlKSB7XG5cbiAgICAgICAgICAgIGNhc2UgJ2VudW0nOlxuXG4gICAgICAgICAgICAgICAgaWYgKCFtb2RlbFtrZXldLnZhbHVlcyB8fCAhQXJyYXkuaXNBcnJheShtb2RlbFtrZXldLnZhbHVlcykpIHtcblxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhwZWN0RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAnRW51bWVyYXRvciBjb25kaXRpb25zIGFycmF5IG5vdCBkZWZpbmVkIGluIHRoZSBtb2RlbCcsXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6ICdlbnVtJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IG1vZGVsW2tleV0udmFsdWVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghbW9kZWxba2V5XS52YWx1ZXMuaW5jbHVkZXModmFsdWUpICYmXG4gICAgICAgICAgICAgICAgICAgIChtb2RlbFtrZXldLnJlcXVpcmVkID09PSB0cnVlIHx8IG1vZGVsW2tleV0ucmVxdWlyZWQgPT09IHVuZGVmaW5lZCkpIHtcblxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhwZWN0RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBgVGhlIHZhbHVlIHR5cGUgb2YgdGhlIFwiJHtTdHJpbmcoa2V5KX1cIiBwcm9wZXJ0eSBpcyBub3QgdmFsaWQuIEV4cGVjdGVkIHR5cGUgb25lIG9mICR7bW9kZWxba2V5XS52YWx1ZXN9IGJ1dCBnb3Q6ICR7U3RyaW5nKHZhbHVlKX1gLFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiAnZW51bScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzOiBtb2RlbFtrZXldLnZhbHVlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnYWRkcmVzcyc6XG5cbiAgICAgICAgICAgICAgICBpZiAoIW5ldyBSZWdFeHAoJ14weFthLWZBLUYwLTldezQwfSQnKS50ZXN0KHZhbHVlKSAmJlxuICAgICAgICAgICAgICAgICAgICAobW9kZWxba2V5XS5yZXF1aXJlZCA9PT0gdHJ1ZSB8fCBtb2RlbFtrZXldLnJlcXVpcmVkID09PSB1bmRlZmluZWQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4cGVjdEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgYEV0aGVyZXVtIGFkZHJlc3MgaXMgcmVxdWlyZWQgYXMgdmFsdWUgZm9yIHRoZSBwcm9wZXJ0eTogXCIke2tleX1cImAsXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6ICdhZGRyZXNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnaGFzaCc6XG5cbiAgICAgICAgICAgICAgICBpZiAoIW5ldyBSZWdFeHAoJ14weFthLWZBLUYwLTldezY0fSQnKS50ZXN0KHZhbHVlKSAmJlxuICAgICAgICAgICAgICAgICAgICAobW9kZWxba2V5XS5yZXF1aXJlZCA9PT0gdHJ1ZSB8fCBtb2RlbFtrZXldLnJlcXVpcmVkID09PSB1bmRlZmluZWQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4cGVjdEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgYEV0aGVyZXVtIHR4IGhhc2ggaXMgcmVxdWlyZWQgYXMgdmFsdWUgZm9yIHRoZSBwcm9wZXJ0eTogXCIke2tleX1cImAsXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6ICdoYXNoJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnYm4nOlxuXG4gICAgICAgICAgICAgICAgaWYgKCF3ZWIzdXRpbHMuaXNCTih2YWx1ZSkgJiZcbiAgICAgICAgICAgICAgICAgICAgKG1vZGVsW2tleV0ucmVxdWlyZWQgPT09IHRydWUgfHwgbW9kZWxba2V5XS5yZXF1aXJlZCA9PT0gdW5kZWZpbmVkKSkge1xuXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeHBlY3RFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIGBCTiBpbnN0YW5jZSBleHBlY3RlZCBhcyB2YWx1ZSBmb3IgdGhlIHByb3BlcnR5IFwiJHtrZXl9XCIgYnV0IGdvdDogJHt2YWx1ZX1gLFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiAnYm4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlICdmdW5jdGlvbk9yTWVtYmVyJzpcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcblxuICAgICAgICAgICAgICAgICAgICAvLyBJdCBpcyBPS1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gSWYgbm90IHRoZW4gZm9sbG93IHRoZSBuZXh0IHJ1bGVcblxuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuICAgICAgICAgICAgY2FzZSAnbWVtYmVyJzpcblxuICAgICAgICAgICAgICAgIGlmICghbW9kZWxba2V5XS5wcm92aWRlciB8fCB0eXBlb2YgbW9kZWxba2V5XS5wcm92aWRlciAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4cGVjdEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgYFByb3ZpZGVyIG9iamVjdCBtdXN0IGJlIGRlZmluZWQgYXMgXCJwcm92aWRlclwiIG1vZGVsIG9wdGlvbiBmb3IgXCIke2tleX1cImBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhwZWN0RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBgUHJvcGVydHkgd2l0aCBcIm1lbWJlclwiIHR5cGUgbXVzdCBiZSBhIHN0cmluZyBidXQgYWN0dWFsbHksIGl0IGlzIGEgXCIke3R5cGVvZiB2YWx1ZX1cImBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY2FzZS1kZWNsYXJhdGlvbnNcbiAgICAgICAgICAgICAgICBjb25zdCBtZW1iZXJWYWx1ZSA9IHZhbHVlLnNwbGl0KCcuJykucmVkdWNlKChhY2MsIHBhcnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFjYyAmJiBhY2NbcGFydF0gIT09IHVuZGVmaW5lZCA/IGFjY1twYXJ0XSA6IG51bGw7XG4gICAgICAgICAgICAgICAgfSwgbW9kZWxba2V5XS5wcm92aWRlcik7XG5cbiAgICAgICAgICAgICAgICBpZiAoIW1lbWJlclZhbHVlKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4cGVjdEVycm9yKCdOb3QgYSBtZW1iZXInLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogbW9kZWxba2V5XS50eXBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXI6IG1vZGVsW2tleV0ucHJvdmlkZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgZGVmYXVsdDpcblxuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB2YWxpZC10eXBlb2ZcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBtb2RlbFtrZXldLnR5cGUgJiZcbiAgICAgICAgICAgICAgICAgICAgKG1vZGVsW2tleV0ucmVxdWlyZWQgPT09IHRydWUgfHwgbW9kZWxba2V5XS5yZXF1aXJlZCA9PT0gdW5kZWZpbmVkKSkge1xuXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeHBlY3RFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIGBUaGUgXCIke2tleX1cIiBwcm9wZXJ0eSB2YWx1ZSBoYXMgYSB3cm9uZyB0eXBlOiAke3R5cGVvZiB2YWx1ZX1gLFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBtb2RlbFtrZXldLnR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufTtcbm1vZHVsZS5leHBvcnRzLmFsbCA9IGFsbDtcbiJdfQ== | ||
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy91dGlscy9leHBlY3QuanMiXSwibmFtZXMiOlsicmVxdWlyZSIsIndlYjN1dGlscyIsInV0aWxzIiwiRXhwZWN0RXJyb3IiLCJtZXNzYWdlIiwiYXJncyIsIkVycm9yIiwibW9kdWxlIiwiZXhwb3J0cyIsImFsbCIsIm9wdGlvbnMiLCJtb2RlbCIsIk9iamVjdCIsImtleXMiLCJsZW5ndGgiLCJrZXkiLCJ0eXBlIiwidmFsdWUiLCJzcGxpdCIsInJlZHVjZSIsImFjYyIsInBhcnQiLCJ1bmRlZmluZWQiLCJyZXF1aXJlZCIsImV4cGVjdGVkIiwidmFsdWVzIiwiQXJyYXkiLCJpc0FycmF5IiwiaW5jbHVkZXMiLCJTdHJpbmciLCJSZWdFeHAiLCJ0ZXN0IiwiaXNCTiIsInByb3ZpZGVyIiwibWVtYmVyVmFsdWUiXSwibWFwcGluZ3MiOiJ1N0hBQTZCQSxPQUFPLENBQUMsTUFBRCxDLENBQXJCQyxTLFVBQVBDLEssQ0FFUjs7OztNQUtNQyxDQUFBQSxXLGtHQUVGOzs7O09BS0Esc0JBQWdELGNBQXBDQyxDQUFBQSxPQUFvQywyREFBMUIsZUFBMEIsbUNBQUU7QUFDOUMsdUJBQU1BLE9BQU4sRUFENEMsOEJBQU5DLElBQU0scURBQU5BLElBQU0seUJBRTVDLE1BQUtBLElBQUwsQ0FBWUEsSUFBWixDQUY0QyxZQUcvQyxDLGtEQVZxQkMsSyxHQVd6QixDQUNEQyxNQUFNLENBQUNDLE9BQVAsQ0FBZUwsV0FBZixDQUE2QkEsV0FBN0IsQ0FFQTs7OztHQUtBLEdBQU1NLENBQUFBLEdBQUcsQ0FBRyxRQUFOQSxDQUFBQSxHQUFNLEVBQThCLElBQTdCQyxDQUFBQSxPQUE2QiwyREFBbkIsRUFBbUIsSUFBZkMsQ0FBQUEsS0FBZSwyREFBUCxFQUFPLENBRXRDLEdBQUksUUFBT0QsT0FBUCxJQUFtQixRQUFuQixFQUErQkUsTUFBTSxDQUFDQyxJQUFQLENBQVlILE9BQVosRUFBcUJJLE1BQXJCLEdBQWdDLENBQW5FLENBQXNFLENBRWxFLEtBQU0sSUFB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Q0FBTCxDQUFXQyxJQUE1QixHQUNDTCxLQUFLLENBQUNJLEdBQUQsQ0FBTCxDQUFXUSxRQUFYLEdBQXdCLElBQXhCLEVBQWdDWixLQUFLLENBQUNJLEdBQUQsQ0FBTCxDQUFXUSxRQUFYLEdBQXdCRCxTQUR6RCxDQUFKLENBQ3lFLENBRXJFLEtBQU0sSUFBSW5CLENBQUFBLFdBQUosaUJBQ01ZLEdBRE4sd0RBQ3NERSxLQUR0RCxHQUVGLENBQ0lPLFFBQVEsQ0FBRWIsS0FBSyxDQUFDSSxHQUFELENBQUwsQ0FBV0MsSUFEekIsQ0FFSUQsR0FBRyxDQUFIQSxHQUZKLENBR0lFLEtBQUssQ0FBTEEsS0FISixDQUZFLENBUVQsQ0EzSVQsQ0E2SUgsQ0FDSixDQWxMRCxDQW1MQVYsTUFBTSxDQUFDQyxPQUFQLENBQWVDLEdBQWYsQ0FBcUJBLEdBQXJCIiwic291cmNlc0NvbnRlbnQiOlsiY29uc3QgeyB1dGlsczogd2ViM3V0aWxzIH0gPSByZXF1aXJlKCd3ZWIzJyk7XG5cbi8qKlxuICogRXhwZWN0RXJyb3IgY2xhc3NcbiAqIEBjbGFzcyBFeHBlY3RFcnJvclxuICogQGV4dGVuZHMge0Vycm9yfVxuICovXG5jbGFzcyBFeHBlY3RFcnJvciBleHRlbmRzIEVycm9yIHtcblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYW4gaW5zdGFuY2Ugb2YgRXhwZWN0RXJyb3IuXG4gICAgICogQHBhcmFtIHtTdHJpbmd9IG1lc3NhZ2VcbiAgICAgKiBAbWVtYmVyb2YgRXhwZWN0RXJyb3JcbiAgICAgKi9cbiAgICBjb25zdHJ1Y3RvcihtZXNzYWdlID0gJ1Vua25vd24gZXJyb3InLCAuLi5hcmdzKSB7IC8vIGVzbGludC1kaXNhYmxlLWxpbmUgc3BhY2UtYmVmb3JlLWZ1bmN0aW9uLXBhcmVuXG4gICAgICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgICAgICB0aGlzLmFyZ3MgPSBhcmdzO1xuICAgIH1cbn07XG5tb2R1bGUuZXhwb3J0cy5FeHBlY3RFcnJvciA9IEV4cGVjdEVycm9yO1xuXG4vKipcbiAqIEVuc3VyaW5nIGV4cGVjdGVkIHBhcmFtZXRlcnMgaGVscGVyXG4gKiBAcGFyYW0ge09iamVjdH0gb3B0aW9uc1xuICogQHBhcmFtIHtPYmplY3R9IG1vZGVsXG4gKi9cbmNvbnN0IGFsbCA9IChvcHRpb25zID0ge30sIG1vZGVsID0ge30pID0+IHtcblxuICAgIGlmICh0eXBlb2Ygb3B0aW9ucyAhPT0gJ29iamVjdCcgfHwgT2JqZWN0LmtleXMob3B0aW9ucykubGVuZ3RoID09PSAwKSB7XG5cbiAgICAgICAgdGhyb3cgbmV3IEV4cGVjdEVycm9yKCdPcHRpb25zIGZvciBcImV4cGVjdC5hbGxcIiBtdXN0IGJlIGFuIG9iamVjdCcpO1xuICAgIH1cblxuICAgIGlmICh0eXBlb2YgbW9kZWwgIT09ICdvYmplY3QnIHx8IE9iamVjdC5rZXlzKG1vZGVsKS5sZW5ndGggPT09IDApIHtcblxuICAgICAgICB0aHJvdyBuZXcgRXhwZWN0RXJyb3IoJ01vZGVsIGZvciBcImV4cGVjdC5hbGxcIiBtdXN0IGJlIGFuIG9iamVjdCcpO1xuICAgIH1cblxuICAgIGZvciAoY29uc3Qga2V5IG9mIE9iamVjdC5rZXlzKG1vZGVsKSkge1xuXG4gICAgICAgIGlmICghbW9kZWxba2V5XS50eXBlKSB7XG5cbiAgICAgICAgICAgIHRocm93IG5ldyBFeHBlY3RFcnJvcignTW9kZWwgcHJvcGVydHkgbXVzdCBoYXZlIGEgXCJ0eXBlXCIgZGVmaW5lZCcpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdmFsdWUgPSBrZXkuc3BsaXQoJy4nKS5yZWR1Y2UoKGFjYywgcGFydCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIGFjYyAmJiBhY2NbcGFydF0gIT09IHVuZGVmaW5lZCA/IGFjY1twYXJ0XSA6IG51bGw7XG4gICAgICAgIH0sIG9wdGlvbnMpO1xuXG4gICAgICAgIGlmIChvcHRpb25zW2tleV0gPT09IHVuZGVmaW5lZCAmJlxuICAgICAgICAgICAgKG1vZGVsW2tleV0ucmVxdWlyZWQgPT09IHRydWUgfHwgbW9kZWxba2V5XS5yZXF1aXJlZCA9PT0gdW5kZWZpbmVkKSkge1xuXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXhwZWN0RXJyb3IoXG4gICAgICAgICAgICAgICAgYFRoZSBcIiR7a2V5fVwiIHByb3BlcnR5IG5vdCBmb3VuZGAsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogbW9kZWxba2V5XS50eXBlLFxuICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN3aXRjaCAobW9kZWxba2V5XS50eXBlKSB7XG5cbiAgICAgICAgICAgIGNhc2UgJ2VudW0nOlxuXG4gICAgICAgICAgICAgICAgaWYgKCFtb2RlbFtrZXldLnZhbHVlcyB8fCAhQXJyYXkuaXNBcnJheShtb2RlbFtrZXldLnZhbHVlcykpIHtcblxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhwZWN0RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICAnRW51bWVyYXRvciBjb25kaXRpb25zIGFycmF5IG5vdCBkZWZpbmVkIGluIHRoZSBtb2RlbCcsXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6ICdlbnVtJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IG1vZGVsW2tleV0udmFsdWVzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghbW9kZWxba2V5XS52YWx1ZXMuaW5jbHVkZXModmFsdWUpICYmXG4gICAgICAgICAgICAgICAgICAgIChtb2RlbFtrZXldLnJlcXVpcmVkID09PSB0cnVlIHx8IG1vZGVsW2tleV0ucmVxdWlyZWQgPT09IHVuZGVmaW5lZCkpIHtcblxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhwZWN0RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBgVGhlIHZhbHVlIHR5cGUgb2YgdGhlIFwiJHtTdHJpbmcoa2V5KX1cIiBwcm9wZXJ0eSBpcyBub3QgdmFsaWQuIEV4cGVjdGVkIHR5cGUgb25lIG9mICR7bW9kZWxba2V5XS52YWx1ZXN9IGJ1dCBnb3Q6ICR7U3RyaW5nKHZhbHVlKX1gLFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiAnZW51bScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVzOiBtb2RlbFtrZXldLnZhbHVlcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnYWRkcmVzcyc6XG5cbiAgICAgICAgICAgICAgICBpZiAoIW5ldyBSZWdFeHAoJ14weFthLWZBLUYwLTldezQwfSQnKS50ZXN0KHZhbHVlKSAmJlxuICAgICAgICAgICAgICAgICAgICAobW9kZWxba2V5XS5yZXF1aXJlZCA9PT0gdHJ1ZSB8fCBtb2RlbFtrZXldLnJlcXVpcmVkID09PSB1bmRlZmluZWQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4cGVjdEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgYEV0aGVyZXVtIGFkZHJlc3MgaXMgcmVxdWlyZWQgYXMgdmFsdWUgZm9yIHRoZSBwcm9wZXJ0eTogXCIke2tleX1cImAsXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6ICdhZGRyZXNzJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnaGFzaCc6XG5cbiAgICAgICAgICAgICAgICBpZiAoIW5ldyBSZWdFeHAoJ14weFthLWZBLUYwLTldezY0fSQnKS50ZXN0KHZhbHVlKSAmJlxuICAgICAgICAgICAgICAgICAgICAobW9kZWxba2V5XS5yZXF1aXJlZCA9PT0gdHJ1ZSB8fCBtb2RlbFtrZXldLnJlcXVpcmVkID09PSB1bmRlZmluZWQpKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4cGVjdEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgYEV0aGVyZXVtIHR4IGhhc2ggaXMgcmVxdWlyZWQgYXMgdmFsdWUgZm9yIHRoZSBwcm9wZXJ0eTogXCIke2tleX1cImAsXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwZWN0ZWQ6ICdoYXNoJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgY2FzZSAnYm4nOlxuXG4gICAgICAgICAgICAgICAgaWYgKCF3ZWIzdXRpbHMuaXNCTih2YWx1ZSkgJiZcbiAgICAgICAgICAgICAgICAgICAgKG1vZGVsW2tleV0ucmVxdWlyZWQgPT09IHRydWUgfHwgbW9kZWxba2V5XS5yZXF1aXJlZCA9PT0gdW5kZWZpbmVkKSkge1xuXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeHBlY3RFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIGBCTiBpbnN0YW5jZSBleHBlY3RlZCBhcyB2YWx1ZSBmb3IgdGhlIHByb3BlcnR5IFwiJHtrZXl9XCIgYnV0IGdvdDogJHt2YWx1ZX1gLFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiAnYm4nLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgICAgICBjYXNlICdmdW5jdGlvbk9yTWVtYmVyJzpcblxuICAgICAgICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdmdW5jdGlvbicpIHtcblxuICAgICAgICAgICAgICAgICAgICAvLyBJdCBpcyBPS1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy8gSWYgbm90IHRoZW4gZm9sbG93IHRoZSBuZXh0IHJ1bGVcblxuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1mYWxsdGhyb3VnaFxuICAgICAgICAgICAgY2FzZSAnbWVtYmVyJzpcblxuICAgICAgICAgICAgICAgIGlmICghbW9kZWxba2V5XS5wcm92aWRlciB8fCB0eXBlb2YgbW9kZWxba2V5XS5wcm92aWRlciAhPT0gJ29iamVjdCcpIHtcbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4cGVjdEVycm9yKFxuICAgICAgICAgICAgICAgICAgICAgICAgYFByb3ZpZGVyIG9iamVjdCBtdXN0IGJlIGRlZmluZWQgYXMgXCJwcm92aWRlclwiIG1vZGVsIG9wdGlvbiBmb3IgXCIke2tleX1cImBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSAnc3RyaW5nJykge1xuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXhwZWN0RXJyb3IoXG4gICAgICAgICAgICAgICAgICAgICAgICBgUHJvcGVydHkgd2l0aCBcIm1lbWJlclwiIHR5cGUgbXVzdCBiZSBhIHN0cmluZyBidXQgYWN0dWFsbHksIGl0IGlzIGEgXCIke3R5cGVvZiB2YWx1ZX1cImBcbiAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgbm8tY2FzZS1kZWNsYXJhdGlvbnNcbiAgICAgICAgICAgICAgICBjb25zdCBtZW1iZXJWYWx1ZSA9IHZhbHVlLnNwbGl0KCcuJykucmVkdWNlKChhY2MsIHBhcnQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGFjYyAmJiBhY2NbcGFydF0gIT09IHVuZGVmaW5lZCA/IGFjY1twYXJ0XSA6IG51bGw7XG4gICAgICAgICAgICAgICAgfSwgbW9kZWxba2V5XS5wcm92aWRlcik7XG5cbiAgICAgICAgICAgICAgICBpZiAoIW1lbWJlclZhbHVlKSB7XG5cbiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEV4cGVjdEVycm9yKCdOb3QgYSBtZW1iZXInLCB7XG4gICAgICAgICAgICAgICAgICAgICAgICBleHBlY3RlZDogbW9kZWxba2V5XS50eXBlLFxuICAgICAgICAgICAgICAgICAgICAgICAgcHJvdmlkZXI6IG1vZGVsW2tleV0ucHJvdmlkZXIsXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgICAgZGVmYXVsdDpcblxuICAgICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSB2YWxpZC10eXBlb2ZcbiAgICAgICAgICAgICAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBtb2RlbFtrZXldLnR5cGUgJiZcbiAgICAgICAgICAgICAgICAgICAgKG1vZGVsW2tleV0ucmVxdWlyZWQgPT09IHRydWUgfHwgbW9kZWxba2V5XS5yZXF1aXJlZCA9PT0gdW5kZWZpbmVkKSkge1xuXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFeHBlY3RFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgICAgIGBUaGUgXCIke2tleX1cIiBwcm9wZXJ0eSB2YWx1ZSBoYXMgYSB3cm9uZyB0eXBlOiAke3R5cGVvZiB2YWx1ZX1gLFxuICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGV4cGVjdGVkOiBtb2RlbFtrZXldLnR5cGUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlXG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufTtcbm1vZHVsZS5leHBvcnRzLmFsbCA9IGFsbDtcbiJdfQ== |
{ | ||
"name": "@windingtree/org.id-resolver", | ||
"version": "0.4.4", | ||
"description": "ORG.ID DID resolver", | ||
"version": "1.0.0", | ||
"description": "ORGiD DID resolver", | ||
"keywords": [ | ||
"org.id", | ||
"orgid", | ||
"did", | ||
@@ -33,4 +33,5 @@ "resolver", | ||
"dependencies": { | ||
"@babel/polyfill": "7.8.7", | ||
"@windingtree/org.id": "0.11.5", | ||
"@babel/polyfill": "7.10.1", | ||
"@windingtree/org.id": "1.0.1", | ||
"@windingtree/org.id-lif-deposit": "1.0.0", | ||
"@windingtree/org.json-schema": "0.3.0", | ||
@@ -41,9 +42,9 @@ "axios": "0.19.2", | ||
"devDependencies": { | ||
"@babel/core": "7.9.6", | ||
"@babel/cli": "7.8.4", | ||
"@babel/preset-env": "7.9.6", | ||
"eslint": "6.8.0", | ||
"mocha": "7.1.2", | ||
"@babel/core": "7.10.3", | ||
"@babel/cli": "7.10.3", | ||
"@babel/preset-env": "7.10.3", | ||
"eslint": "7.3.1", | ||
"mocha": "8.0.1", | ||
"chai": "4.2.0", | ||
"nyc": "15.0.1", | ||
"nyc": "15.1.0", | ||
"coveralls": "3.1.0", | ||
@@ -50,0 +51,0 @@ "ganache-cli": "6.9.1", |
233
README.md
[](https://travis-ci.org/windingtree/org.id-resolver) | ||
[](https://coveralls.io/github/windingtree/org.id-resolver?branch=master&v=2.0) | ||
[](https://coveralls.io/github/windingtree/org.id-resolver?branch=master&v=2.0) | ||
# ORG.ID DID Resolver Library | ||
<a href="https://orgid.tech"><img src="https://github.com/windingtree/branding/raw/master/org.id/svg/org.id-logo.svg" height="50" alt="ORG.ID"></a> | ||
DID Resolver of the Winding Tree ORG.ID protocol | ||
## ORG.ID DID Resolver | ||
## Initial setup | ||
ORG.ID DID Resolver is an application for resolving ORG.ID data in [W3C DID](https://w3c.github.io/did-core/) format. | ||
```bash | ||
## Usage | ||
### Command Line | ||
```sh | ||
git clone git@github.com:windingtree/org.id-resolver.git | ||
cd org.id-resolver | ||
npm i | ||
npm link | ||
chmod +x src/cli.js | ||
``` | ||
## Tests | ||
```bash | ||
npm run test | ||
npm run test ./<path_to_test_file>.js | ||
``` | ||
## Tests coverage | ||
```bash | ||
npm run coverage | ||
``` | ||
## Linting | ||
```bash | ||
npm run lint | ||
```sh | ||
./src/cli.js endpoint=<WEB3_PROVIDER> orgid=<ORGID_ADDRESS> did=did:orgid:0x6d98103810d50b3711ea81c187a48245109ba094644ddbc54f8d0c4c | ||
``` | ||
## Usage | ||
### NPM Module | ||
```bash | ||
$ npm i @windingtree/org.id-resolver | ||
```sh | ||
npm i @windingtree/org.id-resolver | ||
``` | ||
```javascript | ||
@@ -46,8 +36,8 @@ const Web3 = require('web3'); | ||
const web3 = new Web3('<WEB3_PROVIDER_URI>'); | ||
const web3 = new Web3('<WEB3_PROVIDER>'); // HTTP(s) or WS(s) | ||
const resolver = new OrgIdResolver({ | ||
web3, | ||
orgId: '<ORGID_INSTANCE_ADDRESS>' | ||
web3, | ||
orgId: '<ORGID_ADDRESS>' // TODO: #3 | ||
}); | ||
resolver.registerFetchMethod(httpFetchMethod); // Allowing to fetch files from the web | ||
resolver.registerFetchMethod(httpFetchMethod); | ||
@@ -57,81 +47,9 @@ const result = await resolver.resolve('did:orgid:0x62a7502f4c44d8147b8f7b2a1dbeb8503e8446e77355bb2e4ebf999c7ecc5808'); | ||
The result will look like: | ||
## Algorithm | ||
```bash | ||
{ | ||
didDocument: { | ||
'@context': [ | ||
'https://www.w3.org/ns/did/v1', | ||
'https://windingtree.com/ns/orgid/v1' | ||
], | ||
id: 'did:orgid:0x62a7502f4c44d8147b8f7b2a1dbeb8503e8446e77355bb2e4ebf999c7ecc5808', | ||
created: '2019-01-01T13:10:02.251Z', | ||
updated: '2019-06-03T13:20:06.398Z', | ||
publicKey: [ [Object], [Object] ], | ||
service: [ [Object] ], | ||
trust: { assertions: [Array], credentials: [Array] }, | ||
legalEntity: | ||
{ | ||
legalName: 'Acme, Corp.', | ||
alternativeName: 'Acme', | ||
legalIdentifier: 'US12345567', | ||
identifiers: [Array], | ||
legalType: 'GmBH', | ||
registeredAddress: [Object], | ||
locations: [Array], | ||
contacts: [Array] | ||
} | ||
}, | ||
id: '0x62a7502f4c44d8147b8f7b2a1dbeb8503e8446e77355bb2e4ebf999c7ecc5808', | ||
lifDeposit: { | ||
deposit: "1000000000000000000000", | ||
withdrawalRequest: null | ||
}, | ||
errors: [ | ||
{ | ||
"title": "Trust error", | ||
"source": { | ||
"pointer": "trust.assertions[0]" | ||
}, | ||
"detail": "cannot get the proof" | ||
} | ||
], | ||
resolverMetadata: { | ||
"version": "0.2.5", | ||
retrieved: '2020-02-21T18:14:13.278Z', | ||
duration: 979 | ||
} | ||
} | ||
``` | ||
1. Validate DID syntax (must be `did:orgid:bytes32`) | ||
2. Read organization data from ORG.ID Registry | ||
3. Fetch and validate [ORG.JSON](https://github.com/windingtree/org.json-schema): | ||
4. Try to resolve assertions and credentials | ||
## Resolver flow | ||
- DID syntax validation | ||
- Fetching of the DID document | ||
- Comparing hashes of obtained DID document and stored on the ORG.ID smart contract | ||
- Validation DID document object against ORG.ID JSON schema (for more information see the package [@windingtree/org.json-schema](https://github.com/windingtree/org.json-schema)) | ||
- Verification of trust records (if defined in the DID document on the path `trust.assertions`. `trust.credentials` are ignored for now but will be enable in future versions) | ||
- Checking of the Lif deposit status for the organization | ||
If any errors occurred on any step then these errors will be placed to the `errors` section of the resolvers response. | ||
Common schema of the error message is look like: | ||
```json | ||
{ | ||
// Error title, that has {string} value | ||
"title": "Trust error", | ||
"source": { | ||
// The source of the error. In depends on error nature this | ||
// option can be a {string} or {Object} | ||
"pointer": "trust.assertions[0]" | ||
}, | ||
// Error explanation | ||
"detail": "cannot get the proof" | ||
} | ||
``` | ||
## Response Schema | ||
The response of the resolver contains the following information | ||
@@ -151,20 +69,35 @@ | ||
"orgId": "<organization_id>", | ||
"orgJsonHash": "<organization_json_hash>", | ||
"orgJsonUri": "<organization_json_uri>", | ||
"orgJsonHash": "<organization_json_hash>", | ||
"parentEntity": "<parent_organization_hash_or_zero_hash>", | ||
"orgJsonUriBackup1": "<organization_json_uri>", | ||
"orgJsonUriBackup2": "<organization_json_uri>", | ||
"parentOrgId": "<parent_organization_hash_or_zero_hash>", | ||
"owner": "<owner_eth_address>", | ||
"director": "<director_eth_address>", | ||
"state": true,// true for `enabled` and false for `disabled` | ||
"directorConfirmed": true,// director confirmation status | ||
"deposit": "<deposit_value_in_wei>" | ||
"isActive": true,// true for `enabled` and false for `disabled` | ||
"isDirectorshipAccepted": true,// director confirmation status | ||
}, | ||
// List of validation results | ||
"checks": [ | ||
{ | ||
"type": "DID_SYNTAX", | ||
"passed": true, | ||
"errors": [], | ||
"warnings": [] | ||
}, | ||
{ | ||
"type": "ORGID", | ||
"passed": true, | ||
"errors": [], | ||
"warnings": [] | ||
}, | ||
{ | ||
"type": "DID_DOCUMENT", | ||
"passed": true, | ||
"errors": [], | ||
"warnings": [] | ||
} | ||
], | ||
// An object that contains information about Lif deposit | ||
// and deposit withdrawal request existance | ||
"lifDeposit": { | ||
"deposit": "1000000000000000000000", | ||
// null or object with information about request | ||
"withdrawalRequest": null | ||
}, | ||
// Verified trust section of the `didDocument` | ||
@@ -200,20 +133,8 @@ "trust": { | ||
// List of errors that happen during the resolving flow | ||
"errors": [ | ||
{ | ||
"title": "Trust error", | ||
"source": { | ||
"pointer": "trust.assertions[0]" | ||
}, | ||
"detail": "cannot get the proof" | ||
}, | ||
{...} | ||
], | ||
// Resolver meta-data like version, date of result and process duration | ||
"resolverMetadata": { | ||
"version": "0.3.3", | ||
"version": "1.0.0", | ||
"retrieved": "2020-02-21T18:14:13.278Z", | ||
"duration": 979, | ||
"orgIdAddress": "0xc8fD300bE7e4613bCa573ad820a6F1f0b915CfcA" | ||
"orgIdAddress": "0x2cb8dCf26830B969555E04C2EDe3fc1D1BaD504E" | ||
} | ||
@@ -242,13 +163,10 @@ } | ||
```javascript | ||
// Configuration of the custom fetching method | ||
module.exports = { | ||
// Unique fetcher name | ||
name: 'custom_fetcher', | ||
name: 'unique_method_name', | ||
// Regular expression for matching your custom URIs | ||
// Regexp to match your URI schema | ||
pattern: '^yourpatternrule:', | ||
// Fetching function | ||
fetch: async uri => { | ||
const data = await yourCustomFetch(uri); | ||
const data = await yourCustomHandler(uri); | ||
return data; | ||
@@ -259,14 +177,33 @@ } | ||
## CLI | ||
## Development | ||
The resolver can be used as a simple CLI. | ||
### Test | ||
```sh | ||
npm run test | ||
npm run test ./<path_to_test_file>.js | ||
``` | ||
## Test coverage | ||
```bash | ||
$ ./src/cli.js endpoint=<WEB3_PROVIDER_ENTRYPOINT> orgid=<ORG_ID_ADDRESS> did=did:orgid:0x6d98103810d50b3711ea81c187a48245109ba094644ddbc54f8d0c4c | ||
npm run coverage | ||
``` | ||
- WEB3_PROVIDER_ENTRYPOINT: http/https link to you web3 ethereum provider, for example, `https://ropsten.infura.io/v3/<API_KEY>` | ||
- ORG_ID_ADDRESS: The address of an ORG.ID smart contract | ||
- did: unique identifier in the DID format | ||
## Lint | ||
The code of CLI is placed in the [./src](./src/cli.js) directory. You can use this code as a good example of the ORG.ID resolver library usage | ||
```bash | ||
npm run lint | ||
``` | ||
## ORG.ID Ecosystem | ||
 | ||
- [Winding Tree DAO](https://github.com/windingtree/dao) controls ORG.ID Registry smart contract and some Directories (including their rules) | ||
- [ORG.ID Registry](https://github.com/windingtree/org.id) contains records of all organizations and organizational units | ||
- [ORG.JSON Schema](https://github.com/windingtree/org.json-schema) is a data format for describing organizations | ||
- **ORG.ID Resolver (you are here)** | ||
- [ORG.ID Directories](https://github.com/windingtree/org.id-directories) are curated lists of organizations | ||
- [Arbor](https://arbor.fm) can be used to look up an ORG.ID, and also to create and manage your own ORG.ID |
@@ -13,3 +13,3 @@ const axios = require('axios'); | ||
const response = await axios.get(uri, { | ||
transformResponse: [(data) => { return data; }], // Do not convert JSON to object | ||
transformResponse: [data => data], // Do not convert JSON to object | ||
cancelToken: source.token | ||
@@ -16,0 +16,0 @@ }); |
468
src/index.js
@@ -13,12 +13,11 @@ const packageJson = require('../package.json'); | ||
const { getDnsData, ResourceRecordTypes } = require('./dns'); | ||
const { zeroAddress } = require('../test/utils/misc'); | ||
// Errors types definitions | ||
const errors = { | ||
'CORE_ERROR': 'Core error', | ||
'FETCHER_ERROR': 'URI fetcher error', | ||
'DID_SYNTAX_ERROR': 'DID syntax error', | ||
'DID_DOCUMENT_ERROR': 'DID document error', | ||
'TRUST_ASSERTION_ERROR': 'Trust error', | ||
'ORG_ID_ERROR': 'ORG.ID error' | ||
}; | ||
const checksTypes = [ | ||
'DID_SYNTAX', | ||
'ORGID', | ||
'DID_DOCUMENT', | ||
'TRUST_ASSERTIONS' | ||
]; | ||
@@ -36,3 +35,3 @@ /** | ||
*/ | ||
constructor(options = {}) { | ||
constructor (options = {}) { | ||
expect.all(options, { | ||
@@ -65,3 +64,3 @@ web3: { | ||
*/ | ||
reset() { | ||
reset () { | ||
this.validator = new Ajv(); | ||
@@ -71,5 +70,8 @@ this.resolutionStart = null; | ||
didDocument: null, | ||
errors: [], | ||
organization: null, | ||
lifDeposit: null, | ||
checks: checksTypes.map(type => ({ | ||
type, | ||
passed: type === 'TRUST_ASSERTIONS' ? false : true | ||
})), | ||
trust: [], | ||
resolverMetadata: { | ||
@@ -91,3 +93,3 @@ retrieved: null, | ||
*/ | ||
async resolve(did) { | ||
async resolve (did) { | ||
expect.all({ did }, { | ||
@@ -103,19 +105,12 @@ did: { | ||
try { | ||
this.result.id = await this.validateDidSyntax(did); | ||
this.result.organization = | ||
await this.getOrganization(this.result.id); | ||
this.result.didDocument = | ||
await this.getDidDocument(this.result.organization); | ||
await this.validateDidSyntax(did); | ||
await this.getOrganization(this.result.id); | ||
await this.getDidDocument(this.result.organization); | ||
await this.validateDidDocument(this.result.didDocument); | ||
this.result.trust = | ||
await this.verifyTrustRecords(this.result.didDocument); | ||
this.result.lifDeposit = | ||
await this.getLifStakeStatus(this.result.id); | ||
} catch(err) { | ||
this.addErrorMessage({ | ||
type: 'CORE_ERROR', | ||
pointer: 'resolving flow termination', | ||
detail: `Resolving flow has been terminated due to serious error: ${err.message}; ${err.stack}` | ||
}); | ||
await this.verifyTrustRecords(this.result.didDocument); | ||
} catch(error) { | ||
throw new Error( | ||
`Resolving flow has been terminated due to serious error: ${error.message}; ${error.stack}` | ||
); | ||
} | ||
@@ -137,3 +132,3 @@ | ||
*/ | ||
async validateDidSyntax(did) { | ||
async validateDidSyntax (did) { | ||
expect.all({ did }, { | ||
@@ -149,6 +144,5 @@ did: { | ||
this.addErrorMessage({ | ||
type: 'DID_SYNTAX_ERROR', | ||
pointer: did, | ||
detail: `Invalid DID prefix: ${parts[0]}`, | ||
this.addCheckResult({ | ||
type: 'DID_SYNTAX', | ||
error: `Invalid DID prefix: ${parts[0]}`, | ||
throw: true | ||
@@ -160,6 +154,5 @@ }); | ||
this.addErrorMessage({ | ||
type: 'DID_SYNTAX_ERROR', | ||
pointer: did, | ||
detail: `Unsupported DID method: ${parts[1]}`, | ||
this.addCheckResult({ | ||
type: 'DID_SYNTAX', | ||
error: `Unsupported DID method: ${parts[1]}`, | ||
throw: true | ||
@@ -174,6 +167,5 @@ }); | ||
this.addErrorMessage({ | ||
type: 'DID_SYNTAX_ERROR', | ||
pointer: did, | ||
detail: `Invalid method specific Id: ${subParts[0]}`, | ||
this.addCheckResult({ | ||
type: 'DID_SYNTAX', | ||
error: `Invalid method specific Id: ${subParts[0]}`, | ||
throw: true | ||
@@ -183,3 +175,4 @@ }); | ||
return subParts[0]; | ||
this.result.id = subParts[0]; | ||
return this.result.id; | ||
} | ||
@@ -193,3 +186,3 @@ | ||
*/ | ||
async validateDidDocument(didDocument) { | ||
async validateDidDocument (didDocument) { | ||
expect.all({ didDocument }, { | ||
@@ -207,6 +200,5 @@ didDocument: { | ||
this.validator.errors.map(detail => this.addErrorMessage({ | ||
type: 'DID_DOCUMENT_ERROR', | ||
pointer: 'document schema', | ||
detail | ||
this.validator.errors.map(detail => this.addCheckResult({ | ||
type: 'DID_DOCUMENT', | ||
warning: detail | ||
})); | ||
@@ -224,3 +216,3 @@ } | ||
*/ | ||
async verifyTrustRecords(didDocument) { | ||
async verifyTrustRecords (didDocument) { | ||
@@ -243,3 +235,3 @@ if (!didDocument.trust || !Array.isArray(didDocument.trust.assertions)) { | ||
let proofFound = false; | ||
switch (assertion.type) { | ||
@@ -253,6 +245,6 @@ | ||
this.addErrorMessage({ | ||
type: 'TRUST_ASSERTION_ERROR', | ||
pointer: `trust.assertions[${i}]`, | ||
detail: `proof value "${assertion.proof}" not in the range of [${Object.keys(ResourceRecordTypes).join(',')}]` | ||
this.addCheckResult({ | ||
type: 'TRUST_ASSERTIONS', | ||
error: `trust.assertions[${i}]: proof value "${assertion.proof}" | ||
not in the range of [${Object.keys(ResourceRecordTypes).join(',')}]` | ||
}); | ||
@@ -267,6 +259,5 @@ break; | ||
this.addErrorMessage({ | ||
type: 'TRUST_ASSERTION_ERROR', | ||
pointer: `trust.assertions[${i}]`, | ||
detail: 'proof not found' | ||
this.addCheckResult({ | ||
type: 'TRUST_ASSERTIONS', | ||
error: `trust.assertions[${i}]: claim source is empty` | ||
}); | ||
@@ -285,7 +276,6 @@ break; | ||
if (!proofFound) { | ||
this.addErrorMessage({ | ||
type: 'TRUST_ASSERTION_ERROR', | ||
pointer: `trust.assertions[${i}]`, | ||
detail: 'proof not found' | ||
this.addCheckResult({ | ||
type: 'TRUST_ASSERTIONS', | ||
error: `trust.assertions[${i}]: proof not found` | ||
}); | ||
@@ -296,6 +286,5 @@ } | ||
this.addErrorMessage({ | ||
type: 'TRUST_ASSERTION_ERROR', | ||
pointer: `trust.assertions[${i}]`, | ||
detail: 'cannot get the proof' | ||
this.addCheckResult({ | ||
type: 'TRUST_ASSERTIONS', | ||
error: `trust.assertions[${i}]: cannot get the proof` | ||
}); | ||
@@ -311,3 +300,3 @@ break; | ||
case 'domain': | ||
// Validate assertion.proof record | ||
@@ -318,6 +307,5 @@ // should be in the assertion.claim namespace | ||
this.addErrorMessage({ | ||
type: 'TRUST_ASSERTION_ERROR', | ||
pointer: `trust.assertions[${i}]`, | ||
detail: 'claim is not in the domain namespace' | ||
this.addCheckResult({ | ||
type: 'TRUST_ASSERTIONS', | ||
error: `trust.assertions[${i}]: claim is not in the domain namespace` | ||
}); | ||
@@ -335,6 +323,5 @@ break; | ||
this.addErrorMessage({ | ||
type: 'TRUST_ASSERTION_ERROR', | ||
pointer: `trust.assertions[${i}]`, | ||
detail: 'cannot get the proof' | ||
this.addCheckResult({ | ||
type: 'TRUST_ASSERTIONS', | ||
error: `trust.assertions[${i}]: cannot get the proof` | ||
}); | ||
@@ -347,6 +334,5 @@ break; | ||
this.addErrorMessage({ | ||
type: 'TRUST_ASSERTION_ERROR', | ||
pointer: `trust.assertions[${i}]`, | ||
detail: 'DID not found in the claim' | ||
this.addCheckResult({ | ||
type: 'TRUST_ASSERTIONS', | ||
error: `trust.assertions[${i}]: DID not found in the claim` | ||
}); | ||
@@ -362,6 +348,5 @@ break; | ||
// For cases where unknown assertion type has been provided | ||
this.addErrorMessage({ | ||
type: 'TRUST_ASSERTION_ERROR', | ||
pointer: `trust.assertions[${i}]`, | ||
detail: `unknown assertion type: ${assertion.type}` | ||
this.addCheckResult({ | ||
type: 'TRUST_ASSERTIONS', | ||
error: `trust.assertions[${i}]: unknown assertion type "${assertion.type}"` | ||
}); | ||
@@ -373,3 +358,9 @@ } | ||
return trust; | ||
// Just mark as passed | ||
this.addCheckResult({ | ||
type: 'TRUST_ASSERTIONS' | ||
}); | ||
this.result.trust = trust; | ||
return this.result.trust; | ||
} | ||
@@ -383,3 +374,3 @@ | ||
*/ | ||
async fetchFileByUri(uri) { | ||
async fetchFileByUri (uri) { | ||
expect.all({ uri }, { | ||
@@ -391,2 +382,9 @@ uri: { | ||
if (uri === '') { | ||
throw new Error( | ||
'Fetcher error: empty URI' | ||
); | ||
} | ||
let fetch; | ||
@@ -396,8 +394,5 @@ | ||
this.addErrorMessage({ | ||
type: 'FETCHER_ERROR', | ||
pointer: 'incomplete configuration', | ||
detail: 'at least one fetching method should be registered', | ||
throw: true | ||
}); | ||
throw new Error( | ||
'Incomplete configuration: at least one fetching method should be registered' | ||
); | ||
} | ||
@@ -416,8 +411,5 @@ | ||
this.addErrorMessage({ | ||
type: 'FETCHER_ERROR', | ||
pointer: 'incomplete configuration', | ||
detail: `unable to determine the fetching method for URI: ${uri}`, | ||
throw: true | ||
}); | ||
throw new Error( | ||
`Fetcher error: unable to determine the fetching method for URI: ${uri}` | ||
); | ||
} | ||
@@ -430,8 +422,5 @@ | ||
this.addErrorMessage({ | ||
type: 'FETCHER_ERROR', | ||
pointer: uri, | ||
detail: 'file not found by the given URI', | ||
throw: true | ||
}); | ||
throw new Error( | ||
`Fetcher error: file not found by the given URI: ${uri}` | ||
); | ||
} | ||
@@ -448,3 +437,3 @@ | ||
*/ | ||
async getDidDocument(organization = {}) { | ||
async getDidDocument (organization = {}) { | ||
expect.all(organization, { | ||
@@ -456,14 +445,69 @@ orgId: { | ||
type: 'string' | ||
}, | ||
orgJsonUriBackup1: { | ||
type: 'string', | ||
required: false | ||
}, | ||
orgJsonUriBackup2: { | ||
type: 'string', | ||
required: false | ||
} | ||
}); | ||
const didDocument = await this.fetchFileByUri(organization.orgJsonUri); | ||
const { | ||
orgId, | ||
orgJsonHash, | ||
orgJsonUri, | ||
orgJsonUriBackup1, | ||
orgJsonUriBackup2 | ||
} = organization; | ||
// Resolve first settled promise | ||
const firstSettled = async fetches => { | ||
let result; | ||
let errors = []; | ||
for (const fetchPromise of fetches) { | ||
try { | ||
result = await fetchPromise(); | ||
return result; | ||
} catch (error) { | ||
errors.push(error.message); | ||
} | ||
} | ||
if (errors.length) { | ||
throw new Error(errors.join('; ')); | ||
} | ||
throw new Error('Unable to fetch DID Document from given sources'); | ||
}; | ||
let didDocument; | ||
try { | ||
didDocument = await firstSettled( | ||
[ | ||
orgJsonUri, | ||
orgJsonUriBackup1, | ||
orgJsonUriBackup2 | ||
].map( | ||
uri => () => this.fetchFileByUri(uri) | ||
) | ||
); | ||
} catch (error) { | ||
this.addCheckResult({ | ||
type: 'DID_DOCUMENT', | ||
error: error.message, | ||
throw: true | ||
}); | ||
} | ||
// Comparing of the stored and actual hash | ||
if (makeHash(didDocument, this.web3) !== organization.orgJsonHash) { | ||
if (makeHash(didDocument, this.web3) !== orgJsonHash) { | ||
this.addErrorMessage({ | ||
type: 'DID_DOCUMENT_ERROR', | ||
pointer: 'DID document hash', | ||
detail: 'Invalid DID Document hash', | ||
this.addCheckResult({ | ||
type: 'DID_DOCUMENT', | ||
error: 'Invalid DID Document hash', | ||
throw: true | ||
@@ -473,11 +517,11 @@ }); | ||
const didObject = JSON.parse(didDocument); | ||
let didObject; | ||
// DID document should containing a proper DID | ||
if (`did:${this.methodName}:${organization.orgId}` !== didObject.id) { | ||
try { | ||
didObject = JSON.parse(didDocument); | ||
} catch (error) { | ||
this.addErrorMessage({ | ||
type: 'DID_DOCUMENT_ERROR', | ||
pointer: 'DID document id', | ||
detail: `Invalid DID Document id. Expected to be: ${organization.orgId}, but actual is: ${didObject.id}`, | ||
this.addCheckResult({ | ||
type: 'DID_DOCUMENT', | ||
error: 'Broken ORG.JSON. Unable to parse', | ||
throw: true | ||
@@ -487,51 +531,15 @@ }); | ||
return didObject; | ||
} | ||
// DID document should containing a proper DID | ||
if (`did:${this.methodName}:${orgId}` !== didObject.id) { | ||
/** | ||
* Gets a status of the Lif deposit | ||
* @memberof OrgIdResolver | ||
* @param {string} id The organization Id | ||
* @returns {Promise<{Object}>} Lif deposit status | ||
*/ | ||
async getLifStakeStatus(id) { | ||
expect.all({ id }, { | ||
id: { | ||
type: 'string' | ||
} | ||
}); | ||
this.addCheckResult({ | ||
type: 'DID_DOCUMENT', | ||
error: `Invalid DID Document id. Expected to be: ${orgId}, | ||
but actual is: ${didObject.id}`, | ||
throw: true | ||
}); | ||
} | ||
let deposit = 0; | ||
let withdrawalRequest = null; | ||
try { | ||
const organization = await this.getOrganization(id); | ||
deposit = organization.deposit.toString(); | ||
const orgId = await this.getOrgIdContract(); | ||
const requestSource = await orgId | ||
.methods['getWithdrawalRequest(bytes32)'](id).call(); | ||
if (requestSource.exist) { | ||
withdrawalRequest = { | ||
value: requestSource.value.toString(), | ||
withdrawTime: requestSource.withdrawTime.toString() | ||
}; | ||
} | ||
} catch (err) { | ||
if (!RegExp('Withdrawal request not found').test(err.message)) { | ||
this.addErrorMessage({ | ||
type: 'ORG_ID_ERROR', | ||
pointer: 'withdrawal request information', | ||
detail: err.message | ||
}); | ||
} | ||
} | ||
return { | ||
deposit, | ||
withdrawalRequest | ||
}; | ||
this.result.didDocument = didObject; | ||
return this.result.didDocument; | ||
} | ||
@@ -545,3 +553,3 @@ | ||
*/ | ||
async registerFetchMethod(methodConfig = {}) { | ||
async registerFetchMethod (methodConfig = {}) { | ||
expect.all(methodConfig, { | ||
@@ -567,3 +575,3 @@ name: { | ||
*/ | ||
async getOrgIdContract() { | ||
async getOrgIdContract () { | ||
@@ -587,3 +595,3 @@ if (this.cache.orgIdContract) { | ||
*/ | ||
async getOrganization(id) { | ||
async getOrganization (id) { | ||
expect.all({ id }, { | ||
@@ -603,36 +611,57 @@ id: { | ||
if (!org.exist) { | ||
this.addErrorMessage({ | ||
type: 'DID_DOCUMENT_ERROR', | ||
pointer: `Organization: ${id}`, | ||
detail: 'Organization not found', | ||
throw: true | ||
}); | ||
} | ||
const { | ||
exists, | ||
orgId, | ||
orgJsonHash, | ||
orgJsonUri, | ||
orgJsonHash, | ||
parentEntity, | ||
orgJsonUriBackup1, | ||
orgJsonUriBackup2, | ||
parentOrgId, | ||
owner, | ||
director, | ||
state, | ||
directorConfirmed | ||
isActive, | ||
isDirectorshipAccepted | ||
} = org; | ||
if (!exists) { | ||
this.addCheckResult({ | ||
type: 'ORGID', | ||
error: `Organization ${id} not found`, | ||
throw: true | ||
}); | ||
} | ||
if (!isActive) { | ||
this.addCheckResult({ | ||
type: 'ORGID', | ||
warning: `Organization ${id} is disabled` | ||
}); | ||
} | ||
if (director !== zeroAddress && !isDirectorshipAccepted) { | ||
this.addCheckResult({ | ||
type: 'ORGID', | ||
warning: `Directorship of the organization ${id} is not accepted` | ||
}); | ||
} | ||
// Save normalised origanization object | ||
this.cache.organization = { | ||
orgId, | ||
orgJsonHash, | ||
orgJsonUri, | ||
orgJsonHash, | ||
parentEntity, | ||
orgJsonUriBackup1, | ||
orgJsonUriBackup2, | ||
parentOrgId, | ||
owner, | ||
director, | ||
state, | ||
directorConfirmed, | ||
deposit: org.deposit.toString() | ||
isActive, | ||
isDirectorshipAccepted | ||
}; | ||
return this.cache.organization; | ||
this.result.organization = this.cache.organization; | ||
return this.result.organization; | ||
} | ||
@@ -645,3 +674,3 @@ | ||
*/ | ||
getFetchMethods() { | ||
getFetchMethods () { | ||
return Object.keys(this.fetchMethods); | ||
@@ -651,3 +680,3 @@ } | ||
/** | ||
* Adds the error message to the errors set | ||
* Adds a specific check result | ||
* and throws a error if this behaviour is set in the options | ||
@@ -657,12 +686,13 @@ * @memberof OrgIdResolver | ||
*/ | ||
addErrorMessage(options) { | ||
addCheckResult (options) { | ||
expect.all(options, { | ||
type: { | ||
type: 'enum', | ||
values: Object.keys(errors) | ||
values: checksTypes | ||
}, | ||
pointer: { | ||
type: 'string' | ||
error: { | ||
type: 'string', | ||
required: false | ||
}, | ||
detail: { | ||
warning: { | ||
type: 'string', | ||
@@ -677,13 +707,43 @@ required: false | ||
this.result.errors.push({ | ||
title: errors[options.type], | ||
source: { | ||
pointer: options.pointer | ||
}, | ||
detail: options.detail | ||
}); | ||
const { type, error, warning } = options; | ||
// Extract specific check | ||
this.result.checks = this.result.checks.map( | ||
check => { | ||
if (check.type === type) { | ||
check = { | ||
...check, | ||
...( | ||
error | ||
? { | ||
errors: [ | ||
...(check.errors || []), | ||
...[error] | ||
] | ||
} | ||
: {} | ||
), | ||
...( | ||
warning | ||
? { | ||
warnings: [ | ||
...(check.warning || []), | ||
...[warning] | ||
] | ||
} | ||
: {} | ||
) | ||
}; | ||
check.passed = !check.errors || | ||
(check.errors && check.errors.length === 0); | ||
} | ||
return check; | ||
} | ||
); | ||
if (options.throw) { | ||
throw new Error( | ||
`${errors[options.type]}: ${options.pointer}; ${options.detail}` | ||
`${type}: ${error}` | ||
); | ||
@@ -696,2 +756,2 @@ } | ||
module.exports.httpFetchMethod = httpFetchMethod; | ||
module.exports.errorsDefinitions = Object.assign({}, errors); | ||
module.exports.checksTypes = Object.assign({}, checksTypes); |
process.env.TESTING = true; | ||
const { ganache, defaults } = require('../utils/ganache'); | ||
const { assertFailure } = require('../utils/assertions'); | ||
const { setupOrgId } = require('../utils/setup'); | ||
const { setupHttpServer, setupOrgId, createOrganization } = require('../utils/setup'); | ||
const cli = require('../../src/cli'); | ||
@@ -16,4 +16,6 @@ | ||
let orgId; | ||
let organization; | ||
before(async () => { | ||
await setupHttpServer(); | ||
server = await ganache(defaults); | ||
@@ -30,6 +32,7 @@ const accounts = await web3.eth.getAccounts(); | ||
orgId = await setupOrgId(orgIdOwner); | ||
organization = await createOrganization(orgId, orgIdOwner); | ||
defaultArgv = [ | ||
'/home/[user]/.nvm/versions/node/v10.19.0/bin/node', | ||
'/home/[user]/dev/orgid-resolver-remote/src/cli.js', | ||
'did=did:orgid:0x6d98103810d50b3711ea81c187a48245109ba094644ddbc54f8d0c4ca772e8aa', | ||
`did=did:orgid:${organization}`, | ||
`orgid=${orgId.address}` | ||
@@ -36,0 +39,0 @@ ]; |
@@ -23,2 +23,3 @@ const { ganache, defaults } = require('../utils/ganache'); | ||
} = require('../utils/lif'); | ||
const { toChecksObject } = require('../utils/resolver'); | ||
@@ -235,3 +236,2 @@ require('chai').should(); | ||
describe('#validateDidDocument', () => { | ||
it('should fail if did document not been provided', async () => { | ||
@@ -244,12 +244,16 @@ await assertFailure( | ||
it('should return errors if document not been valid', async () => { | ||
it('should return warnings if document not been valid', async () => { | ||
const result = await resolver.validateDidDocument(invalidJson); | ||
(result).should.be.false; | ||
(resolver.result.errors).should.be.an('array').that.is.not.empty; | ||
const checks = toChecksObject(resolver.result.checks); | ||
(checks.DID_DOCUMENT.passed).should.be.true; | ||
(checks.DID_DOCUMENT.warnings).should.be.an('array').that.is.not.empty; | ||
}); | ||
it('should not return errors if document has been valid', async () => { | ||
it('should not warnings errors if document has been valid', async () => { | ||
const result = await resolver.validateDidDocument(validJson); | ||
(result).should.be.true; | ||
(resolver.result.errors).should.be.an('array').that.is.empty; | ||
const checks = toChecksObject(resolver.result.checks); | ||
(checks.DID_DOCUMENT.passed).should.be.true; | ||
(checks.DID_DOCUMENT.warnings).should.be.an('array').that.is.empty; | ||
}); | ||
@@ -269,5 +273,7 @@ }); | ||
await resolver.verifyTrustRecords(didDocument); | ||
(resolver.result.errors).should.be.an('array').that.is.not.empty; | ||
(resolver.result.errors[0]).should.has.property('detail').to.equal( | ||
`proof value "UNKNOWN" not in the range of [${Object.keys(ResourceRecordTypes).join(',')}]` | ||
const checks = toChecksObject(resolver.result.checks); | ||
(checks.TRUST_ASSERTIONS.passed).should.be.false; | ||
(checks.TRUST_ASSERTIONS.errors).should.be.an('array').that.is.not.empty; | ||
(checks.TRUST_ASSERTIONS.errors[0]).should.contain( | ||
`not in the range of [${Object.keys(ResourceRecordTypes).join(',')}]` | ||
); | ||
@@ -279,4 +285,6 @@ }); | ||
await resolver.verifyTrustRecords(didDocument); | ||
(resolver.result.errors).should.be.an('array').that.is.not.empty; | ||
(resolver.result.errors[0]).should.has.property('detail').to.equal( | ||
const checks = toChecksObject(resolver.result.checks); | ||
(checks.TRUST_ASSERTIONS.passed).should.be.false; | ||
(checks.TRUST_ASSERTIONS.errors).should.be.an('array').that.is.not.empty; | ||
(checks.TRUST_ASSERTIONS.errors[0]).should.contain( | ||
'cannot get the proof' | ||
@@ -289,4 +297,6 @@ ); | ||
await resolver.verifyTrustRecords(didDocument); | ||
(resolver.result.errors).should.be.an('array').that.is.not.empty; | ||
(resolver.result.errors[0]).should.has.property('detail').to.equal( | ||
const checks = toChecksObject(resolver.result.checks); | ||
(checks.TRUST_ASSERTIONS.passed).should.be.false; | ||
(checks.TRUST_ASSERTIONS.errors).should.be.an('array').that.is.not.empty; | ||
(checks.TRUST_ASSERTIONS.errors[0]).should.contain( | ||
'cannot get the proof' | ||
@@ -299,3 +309,6 @@ ); | ||
await resolver.verifyTrustRecords(didDocument); | ||
(resolver.result.errors).should.be.an('array').that.is.empty; | ||
const checks = toChecksObject(resolver.result.checks); | ||
(checks.TRUST_ASSERTIONS.passed).should.be.false; | ||
(checks.TRUST_ASSERTIONS.warnings).should.be.an('array').that.is.empty; | ||
(checks.TRUST_ASSERTIONS.errors).should.be.an('array').that.is.empty; | ||
}); | ||
@@ -305,3 +318,6 @@ | ||
await resolver.verifyTrustRecords(didDocument); | ||
(resolver.result.errors).should.be.an('array').that.is.empty; | ||
const checks = toChecksObject(resolver.result.checks); | ||
(checks.TRUST_ASSERTIONS.passed).should.be.true; | ||
(checks.TRUST_ASSERTIONS.warnings).should.be.an('array').that.is.empty; | ||
(checks.TRUST_ASSERTIONS.errors).should.be.an('array').that.is.empty; | ||
}); | ||
@@ -373,3 +389,3 @@ }); | ||
describe('#getLifStakeStatus', () => { | ||
describe.skip('#getLifStakeStatus', () => { | ||
let lifToken; | ||
@@ -422,27 +438,27 @@ | ||
describe('#resolve', () => { | ||
let lifToken; | ||
// let lifToken; | ||
beforeEach(async () => { | ||
const tokenAddress = await orgId | ||
.methods['getLifTokenAddress()']().call(); | ||
lifToken = await lifTokenAtAddress(tokenAddress); | ||
await distributeLifTokens( | ||
lifToken, | ||
orgIdOwner, | ||
'2000', | ||
[ legalEntityOwner ] | ||
); | ||
await lifToken | ||
.methods['approve(address,uint256)']( | ||
orgId.address, | ||
toWeiEther('1000') | ||
) | ||
.send({ from: legalEntityOwner }); | ||
await orgId | ||
.methods['addDeposit(bytes32,uint256)']( | ||
legalEntity, | ||
toWeiEther('1000') | ||
) | ||
.send({ from: legalEntityOwner }); | ||
}); | ||
// beforeEach(async () => { | ||
// const tokenAddress = await orgId | ||
// .methods['getLifTokenAddress()']().call(); | ||
// lifToken = await lifTokenAtAddress(tokenAddress); | ||
// await distributeLifTokens( | ||
// lifToken, | ||
// orgIdOwner, | ||
// '2000', | ||
// [ legalEntityOwner ] | ||
// ); | ||
// await lifToken | ||
// .methods['approve(address,uint256)']( | ||
// orgId.address, | ||
// toWeiEther('1000') | ||
// ) | ||
// .send({ from: legalEntityOwner }); | ||
// await orgId | ||
// .methods['addDeposit(bytes32,uint256)']( | ||
// legalEntity, | ||
// toWeiEther('1000') | ||
// ) | ||
// .send({ from: legalEntityOwner }); | ||
// }); | ||
@@ -463,5 +479,6 @@ it('should fail if did not been provided', async () => { | ||
const result = await resolver.resolve(`did:orgid:${legalEntityInvalidJson}`); | ||
(result).should.be.an('object') | ||
.that.include.property('errors') | ||
.that.an('array') | ||
(result.didDocument).should.be.an('object'); | ||
const checks = toChecksObject(resolver.result.checks); | ||
(checks.DID_DOCUMENT.passed).should.be.true; | ||
(checks.DID_DOCUMENT.warnings).should.be.an('array') | ||
.that.is.not.empty; | ||
@@ -468,0 +485,0 @@ }); |
@@ -9,3 +9,3 @@ const http = require('http'); | ||
constructor() { | ||
constructor () { | ||
this.port = port++; | ||
@@ -22,3 +22,3 @@ this.mime = { | ||
async start() { | ||
async start () { | ||
this.server = http.createServer(this.requestHandler.bind(this)); | ||
@@ -34,3 +34,3 @@ return await new Promise( | ||
async close() { | ||
async close () { | ||
if (this.server) { | ||
@@ -42,3 +42,3 @@ this.server.close(); | ||
requestHandler(request, response) { | ||
requestHandler (request, response) { | ||
const link = url.parse(request.url); | ||
@@ -60,3 +60,3 @@ const path = link.path.replace(/^\//, ''); | ||
async addFile(file) { | ||
async addFile (file) { | ||
expect.all(file, { | ||
@@ -80,3 +80,3 @@ content: { | ||
async removeFile(path) { | ||
async removeFile (path) { | ||
expect.all({ path }, { | ||
@@ -83,0 +83,0 @@ path: { |
@@ -67,2 +67,11 @@ const { TestHelper } = require('@openzeppelin/cli'); | ||
/** | ||
* Generates Id from owner adress and solt | ||
* @param {String} owner Owner address | ||
* @param {String} solt Solt | ||
* @returns {string} | ||
*/ | ||
const generateIdWithSolt = (owner, solt) => web3.utils.soliditySha3(owner, solt); | ||
module.exports.generateIdWithSolt = generateIdWithSolt; | ||
/** | ||
* Generates trus assertions records | ||
@@ -133,3 +142,3 @@ * @param {string} did DID | ||
/** | ||
* Generates a set of value: Id, Uri and Hash | ||
* Generates a set of values: Id, Uri and Hash | ||
* @param {string} from The address of the organization owner | ||
@@ -145,3 +154,4 @@ * @param {Object} jsonObject Organization json object | ||
) => { | ||
const id = generateId(`${from}${Math.random().toString()}`); | ||
const solt = generateId(); | ||
const id = generateIdWithSolt(from, solt); | ||
const did = `did:orgid:${fakeId ? fakeId : id}`; | ||
@@ -186,2 +196,3 @@ const orgJson = Object.assign( | ||
return { | ||
solt, | ||
id, | ||
@@ -195,7 +206,7 @@ uri, | ||
/** | ||
* Create new ORG.ID instance | ||
* @param {string} owner Org.Id owner address | ||
* Create new OrgId instance | ||
* @param {string} from Org.Id owner address | ||
* @returns {Promise<{Object}>} OrgId contact instancr | ||
*/ | ||
const setupOrgId = async (owner) => { | ||
const setupOrgId = async from => { | ||
Contracts.setArtifactsDefaults({ | ||
@@ -206,7 +217,5 @@ gas: 0xfffffffffff | ||
const lifToken = await setupLifToken(owner); | ||
const OrgId = Contracts.getFromNodeModules('@windingtree/org.id', 'OrgId'); | ||
const project = await TestHelper({ | ||
from: owner | ||
from | ||
}); | ||
@@ -221,4 +230,3 @@ await project.setImplementation( | ||
initArgs: [ | ||
owner, | ||
lifToken.address | ||
from | ||
] | ||
@@ -230,2 +238,33 @@ }); | ||
/** | ||
* Create new LifDeposit instance | ||
* @param {Object} orgId OrgId contract instance | ||
* @param {string} from OrgId owner address | ||
* @returns {Promise<{Object}>} OrgId contact instance | ||
*/ | ||
const setupLifDeposit = async (orgId, from) => { | ||
const lifToken = await setupLifToken(from); | ||
const LifDeposit = Contracts.getFromNodeModules( | ||
'@windingtree/org.id-lif-deposit', | ||
'LifDeposit' | ||
); | ||
const project = await TestHelper({ | ||
from | ||
}); | ||
await project.setImplementation( | ||
LifDeposit, | ||
'LifDeposit' | ||
); | ||
return await project.createProxy(LifDeposit, { | ||
initMethod: 'initialize', | ||
initArgs: [ | ||
from, | ||
orgId.address, | ||
lifToken.address | ||
] | ||
}); | ||
}; | ||
module.exports.setupLifDeposit = setupLifDeposit; | ||
/** | ||
* Create an organizations | ||
@@ -248,3 +287,3 @@ * @param {Object} orgId OrgId contract instance | ||
) => { | ||
const { id, uri, hash } = await generateIdSet( | ||
const { solt, id, uri, hash } = await generateIdSet( | ||
from, | ||
@@ -256,6 +295,8 @@ jsonFile ? jsonFile : legalEntityJson, | ||
await orgId | ||
.methods['createOrganization(bytes32,string,bytes32)']( | ||
id, | ||
.methods['createOrganization(bytes32,bytes32,string,string,string)']( | ||
solt, | ||
fakeHash? fakeHash : hash, | ||
fakeUri ? fakeUri : uri, | ||
fakeHash? fakeHash : hash | ||
'', | ||
'' | ||
) | ||
@@ -268,3 +309,3 @@ .send({ from }); | ||
/** | ||
* Create subsidiary organization | ||
* Create unit organization | ||
* @param {Object} orgId OrgId contract instance | ||
@@ -278,5 +319,5 @@ * @param {string} from The address of the organization owner | ||
* @param {string} fakeId Fake id to set | ||
* @returns {Promise<{bool}>} Subsidiary Id | ||
* @returns {Promise<{bool}>} Unit Id | ||
*/ | ||
const createSubsidiary = async ( | ||
const createUnit = async ( | ||
orgId, | ||
@@ -291,3 +332,3 @@ from, | ||
) => { | ||
const { id, uri, hash } = await generateIdSet( | ||
const { solt, id, uri, hash } = await generateIdSet( | ||
from, | ||
@@ -299,8 +340,10 @@ jsonFile ? jsonFile : organizationalUnitJson, | ||
await orgId | ||
.methods['createSubsidiary(bytes32,bytes32,address,string,bytes32)']( | ||
.methods['createUnit(bytes32,bytes32,address,bytes32,string,string,string)']( | ||
solt, | ||
parentId, | ||
id, | ||
director, | ||
fakeHash? fakeHash : hash, | ||
fakeUri ? fakeUri : uri, | ||
fakeHash? fakeHash : hash | ||
'', | ||
'' | ||
) | ||
@@ -310,6 +353,6 @@ .send({ from }); | ||
}; | ||
module.exports.createSubsidiary = createSubsidiary; | ||
module.exports.createUnit = createUnit; | ||
/** | ||
* Setup organizations (main and subsidiary) | ||
* Setup organizations (main and unit) | ||
* @param {string} legalEntityOwner Entity Owner Account addresses | ||
@@ -341,3 +384,3 @@ * @param {string} orgUnitOwner Unit OwnerAccount addresses | ||
const orgUnit = await createSubsidiary( | ||
const orgUnit = await createUnit( | ||
orgId, | ||
@@ -344,0 +387,0 @@ legalEntityOwner, |
Sorry, the diff of this file is too big to display
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
254131
45
3604
1
6
204
+ Added@babel/polyfill@7.10.1(transitive)
+ Added@windingtree/org.id@1.0.1(transitive)
+ Added@windingtree/org.id-lif-deposit@1.0.0(transitive)
- Removed@babel/polyfill@7.8.7(transitive)
- Removed@windingtree/org.id@0.11.5(transitive)
Updated@babel/polyfill@7.10.1
Updated@windingtree/org.id@1.0.1