diff --git a/.eslintrc.json b/.eslintrc.json new file mode 100644 index 0000000..9dae37a --- /dev/null +++ b/.eslintrc.json @@ -0,0 +1,30 @@ +{ + "parser": "@typescript-eslint/parser", + "plugins": [ + "@typescript-eslint" + ], + "extends": [ + "eslint:recommended", + "plugin:@typescript-eslint/eslint-recommended", + "plugin:@typescript-eslint/recommended", + "plugin:import/errors", + "plugin:import/warnings", + "plugin:import/typescript" + ], + "rules": { + "@typescript-eslint/ban-ts-ignore": 0, + "@typescript-eslint/camelcase": 0, + "@typescript-eslint/explicit-function-return-type": 0, + "@typescript-eslint/interface-name-prefix": 0, + "@typescript-eslint/no-explicit-any": 0, + "@typescript-eslint/semi": 1, + "semi": "off", + "import/order": ["error", { + "groups": ["builtin", "external", "internal"], + "alphabetize": { + "order": "asc", + "caseInsensitive": true + } + }] + } +} \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 5fc36b5..1376ccf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -145,30 +145,130 @@ "tslib": "^1.10.0" } }, - "@types/estree": { - "version": "0.0.42", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-0.0.42.tgz", - "integrity": "sha512-K1DPVvnBCPxzD+G51/cxVIoc2X8uUVl1zpJeE6iKcgHMj4+tbat5Xu4TjV7v2QSDbIeAfLi2hIk+u2+s0MlpUQ==", + "@types/color-name": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "dev": true + }, + "@types/eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-OCutwjDZ4aFS6PB1UZ988C4YgwlBHJd6wCeQqaLdmadZ/7e+w79+hbMUFC1QXDNCmdyoRfAFdm0RypzwR+Qpag==", + "dev": true + }, + "@types/json-schema": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", + "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==", "dev": true }, "@types/mocha": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", - "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", + "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", "dev": true }, "@types/node": { - "version": "12.12.29", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.29.tgz", - "integrity": "sha512-yo8Qz0ygADGFptISDj3pOC9wXfln/5pQaN/ysDIzOaAWXt73cNHmtEC8zSO2Y+kse/txmwIAJzkYZ5fooaS5DQ==", + "version": "12.12.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.30.tgz", + "integrity": "sha512-sz9MF/zk6qVr3pAnM0BSQvYIBK44tS75QC5N+VbWSE4DjCV/pJ+UzCW/F+vVnl7TkOPcuwQureKNtSSwjBTaMg==", "dev": true }, + "@typescript-eslint/eslint-plugin": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-2.23.0.tgz", + "integrity": "sha512-8iA4FvRsz8qTjR0L/nK9RcRUN3QtIHQiOm69FzV7WS3SE+7P7DyGGwh3k4UNR2JBbk+Ej2Io+jLAaqKibNhmtw==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "2.23.0", + "eslint-utils": "^1.4.3", + "functional-red-black-tree": "^1.0.1", + "regexpp": "^3.0.0", + "tsutils": "^3.17.1" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-2.23.0.tgz", + "integrity": "sha512-OswxY59RcXH3NNPmq+4Kis2CYZPurRU6mG5xPcn24CjFyfdVli5mySwZz/g/xDbJXgDsYqNGq7enV0IziWGXVQ==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.3", + "@typescript-eslint/typescript-estree": "2.23.0", + "eslint-scope": "^5.0.0" + } + }, + "@typescript-eslint/parser": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-2.23.0.tgz", + "integrity": "sha512-k61pn/Nepk43qa1oLMiyqApC6x5eP5ddPz6VUYXCAuXxbmRLqkPYzkFRKl42ltxzB2luvejlVncrEpflgQoSUg==", + "dev": true, + "requires": { + "@types/eslint-visitor-keys": "^1.0.0", + "@typescript-eslint/experimental-utils": "2.23.0", + "@typescript-eslint/typescript-estree": "2.23.0", + "eslint-visitor-keys": "^1.1.0" + } + }, + "@typescript-eslint/typescript-estree": { + "version": "2.23.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-2.23.0.tgz", + "integrity": "sha512-pmf7IlmvXdlEXvE/JWNNJpEvwBV59wtJqA8MLAxMKLXNKVRC3HZBXR/SlZLPWTCcwOSg9IM7GeRSV3SIerGVqw==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "eslint-visitor-keys": "^1.1.0", + "glob": "^7.1.6", + "is-glob": "^4.0.1", + "lodash": "^4.17.15", + "semver": "^6.3.0", + "tsutils": "^3.17.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, "acorn": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.1.tgz", "integrity": "sha512-add7dgA5ppRPxCFJoAGfMDi7PIBXq1RtGo7BhbLaxwrXPOmw8gq48Y9ozT01hUKy9byMjlR20EJhu5zlkErEkg==", "dev": true }, + "acorn-jsx": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==", + "dev": true + }, "ajv": { "version": "6.10.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", @@ -187,6 +287,23 @@ "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", "dev": true }, + "ansi-escapes": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", + "dev": true, + "requires": { + "type-fest": "^0.11.0" + }, + "dependencies": { + "type-fest": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", + "dev": true + } + } + }, "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", @@ -202,6 +319,16 @@ "color-convert": "^1.9.0" } }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, "append-transform": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-1.0.0.tgz", @@ -232,6 +359,74 @@ "sprintf-js": "~1.0.2" } }, + "array-includes": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.1.tgz", + "integrity": "sha512-c2VXaCHl7zPsvpkFsw4nxvFie4fh1ur9bpcgsVkIjqn0H/Xwdg+7fv3n2r/isyS8EBj5b06M9kHyZuIr4El6WQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0", + "is-string": "^1.0.5" + }, + "dependencies": { + "es-abstract": { + "version": "1.17.4", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.4.tgz", + "integrity": "sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + } + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + } + } + }, + "array.prototype.flat": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.2.3.tgz", + "integrity": "sha512-gBlRZV0VSmfPIeWfuuy56XZMvbVfbEUnOXUvt3F/eUUUSyzlgLxhEX4YAEpxNAogRGehPSnfXyPtYyKAhkzQhQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, "asn1": { "version": "0.2.4", "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", @@ -255,6 +450,12 @@ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", "dev": true }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", @@ -288,6 +489,12 @@ "tweetnacl": "^0.14.3" } }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true + }, "brace-expansion": { "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", @@ -298,6 +505,15 @@ "concat-map": "0.0.1" } }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, "browser-stdout": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", @@ -310,12 +526,6 @@ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", "dev": true }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, "caching-transform": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-3.0.2.tgz", @@ -328,6 +538,12 @@ "write-file-atomic": "^2.4.2" } }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, "camelcase": { "version": "5.3.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", @@ -362,6 +578,43 @@ } } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + } + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, "cliui": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", @@ -403,12 +656,6 @@ "delayed-stream": "~1.0.0" } }, - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true - }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -421,6 +668,12 @@ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", "dev": true }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, "convert-source-map": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", @@ -507,6 +760,12 @@ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", "dev": true }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, "default-require-extensions": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-2.0.0.tgz", @@ -537,6 +796,15 @@ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, "ecc-jsbn": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", @@ -613,12 +881,441 @@ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", "dev": true }, + "eslint": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", + "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.10.0", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^5.0.0", + "eslint-utils": "^1.4.3", + "eslint-visitor-keys": "^1.1.0", + "espree": "^6.1.2", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob-parent": "^5.0.0", + "globals": "^12.1.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^7.0.0", + "is-glob": "^4.0.0", + "js-yaml": "^3.13.1", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.14", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.3", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^6.1.2", + "strip-ansi": "^5.2.0", + "strip-json-comments": "^3.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0", + "v8-compile-cache": "^2.0.3" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "globals": { + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", + "dev": true, + "requires": { + "type-fest": "^0.8.1" + } + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-json-comments": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", + "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", + "dev": true + } + } + }, + "eslint-import-resolver-node": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.3.tgz", + "integrity": "sha512-b8crLDo0M5RSe5YG8Pu2DYBj71tSB6OvXkfzwbJU2w7y8P4/yo0MyF8jU26IEuEuHF2K5/gcAJE3LhQGqBBbVg==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.13.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-module-utils": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.5.2.tgz", + "integrity": "sha512-LGScZ/JSlqGKiT8OC+cYRxseMjyqt6QO54nl281CK93unD89ijSeRV6An8Ci/2nvWVKe8K/Tqdm75RQoIOCr+Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "pkg-dir": "^2.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.20.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.20.1.tgz", + "integrity": "sha512-qQHgFOTjguR+LnYRoToeZWT62XM55MBVXObHM6SKFd1VzDcX/vqT1kAz8ssqigh5eMj8qXcRoXXGZpPP6RfdCw==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "array.prototype.flat": "^1.2.1", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.1", + "has": "^1.0.3", + "minimatch": "^3.0.4", + "object.values": "^1.1.0", + "read-pkg-up": "^2.0.0", + "resolve": "^1.12.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "resolve": { + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + } + } + }, + "eslint-scope": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", + "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", + "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", + "dev": true, + "requires": { + "eslint-visitor-keys": "^1.1.0" + } + }, + "eslint-visitor-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", + "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", + "dev": true + }, + "espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + } + }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", "dev": true }, + "esquery": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.1.0.tgz", + "integrity": "sha512-MxYW9xKmROWF672KqjO75sszsA8Mxhw06YFeS5VHlB98KDHbOSurm3ArsjO60Eaf3QmGMCP1yn+0JQkNLo/97Q==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, "estree-walker": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", @@ -652,6 +1349,17 @@ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "extsprintf": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", @@ -670,6 +1378,39 @@ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", "dev": true }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, "find-cache-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", @@ -699,6 +1440,34 @@ "is-buffer": "~2.0.3" } }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "dependencies": { + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "flatted": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", + "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", + "dev": true + }, "foreground-child": { "version": "1.5.6", "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-1.5.6.tgz", @@ -755,12 +1524,25 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "dev": true, + "optional": true + }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "dev": true }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, "get-caller-file": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", @@ -799,6 +1581,15 @@ "path-is-absolute": "^1.0.0" } }, + "glob-parent": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", + "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, "globals": { "version": "11.12.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", @@ -906,6 +1697,31 @@ "sshpk": "^1.7.0" } }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", + "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -928,6 +1744,117 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "inquirer": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.1.0.tgz", + "integrity": "sha512-5fJMWEmikSYu0nv/flMc475MhGbB7TSPd/2IpFV4I4rMklboCH2rQjYY5kKiYGHqUF9gvaambupcJFFG9dvReg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", + "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", @@ -940,6 +1867,15 @@ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", "dev": true }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, "is-buffer": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", @@ -958,12 +1894,39 @@ "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", "dev": true }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "dev": true }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, "is-regex": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", @@ -979,6 +1942,12 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "is-string": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.5.tgz", + "integrity": "sha512-buY6VNRjhQMiF1qWDouloZlQbRhDPCebwxSjxMjxgemYT46YMd2NR0/H+fBhEfWX4A/w9TBJ+ol+okqJKFE6vQ==", + "dev": true + }, "is-symbol": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", @@ -994,6 +1963,12 @@ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", "dev": true }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1166,6 +2141,12 @@ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", "dev": true }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", @@ -1208,6 +2189,16 @@ "integrity": "sha1-6w1GtUER68VhrLTECO+TY73I9+A=", "dev": true }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -1257,12 +2248,12 @@ "dev": true }, "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz", + "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==", "dev": true, "requires": { - "chalk": "^2.0.1" + "chalk": "^2.4.2" } }, "lru-cache": { @@ -1382,13 +2373,14 @@ } }, "mocha": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.2.tgz", - "integrity": "sha512-FgDS9Re79yU1xz5d+C4rv1G7QagNGHZ+iXF81hO8zY35YZZcLEsJVfFolfsqKFWunATEvNzMK0r/CwWd/szO9A==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.0.tgz", + "integrity": "sha512-MymHK8UkU0K15Q/zX7uflZgVoRWiTjy0fXE/QjKts6mowUvGxOdPhZ2qj3b0iZdUrNZlW9LAIMFHB4IW+2b3EQ==", "dev": true, "requires": { "ansi-colors": "3.2.3", "browser-stdout": "1.3.1", + "chokidar": "3.3.0", "debug": "3.2.6", "diff": "3.5.0", "escape-string-regexp": "1.0.5", @@ -1397,11 +2389,11 @@ "growl": "1.10.5", "he": "1.2.0", "js-yaml": "3.13.1", - "log-symbols": "2.2.0", + "log-symbols": "3.0.0", "minimatch": "3.0.4", "mkdirp": "0.5.1", "ms": "2.1.1", - "node-environment-flags": "1.0.5", + "node-environment-flags": "1.0.6", "object.assign": "4.1.0", "strip-json-comments": "2.0.1", "supports-color": "6.0.0", @@ -1496,6 +2488,18 @@ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", "dev": true }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, "neo-async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", @@ -1515,9 +2519,9 @@ "dev": true }, "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", "dev": true, "requires": { "object.getownpropertydescriptors": "^2.0.3", @@ -1536,6 +2540,12 @@ "validate-npm-package-license": "^3.0.1" } }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, "npm-run-path": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", @@ -1635,6 +2645,18 @@ "es-abstract": "^1.17.0-next.1" } }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, "once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1644,6 +2666,15 @@ "wrappy": "1" } }, + "onetime": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", @@ -1662,6 +2693,20 @@ } } }, + "optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.6", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "word-wrap": "~1.2.3" + } + }, "os-homedir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", @@ -1679,6 +2724,12 @@ "mem": "^4.0.0" } }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, "p-defer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", @@ -1733,6 +2784,15 @@ "release-zalgo": "^1.0.0" } }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, "parse-json": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", @@ -1790,6 +2850,12 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", "dev": true }, + "picomatch": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", + "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", + "dev": true + }, "pify": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", @@ -1805,6 +2871,18 @@ "find-up": "^3.0.0" } }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", @@ -1873,6 +2951,21 @@ "read-pkg": "^3.0.0" } }, + "readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.4" + } + }, + "regexpp": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.0.0.tgz", + "integrity": "sha512-Z+hNr7RAVWxznLPuA7DIh8UNX1j9CDrUQxskw9IrBE1Dxue2lyXT+shqEIeLUjrokxIP8CMy1WkjgG3rTsd5/g==", + "dev": true + }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -1937,6 +3030,16 @@ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", "dev": true }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -1947,37 +3050,35 @@ } }, "rollup": { - "version": "1.32.1", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-1.32.1.tgz", - "integrity": "sha512-/2HA0Ec70TvQnXdzynFffkjA6XN+1e2pEv/uKS5Ulca40g2L7KuOE3riasHoNVHOsFD5KKZgDsMk1CP3Tw9s+A==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-2.0.6.tgz", + "integrity": "sha512-P42IlI6a/bxh52ed8hEXXe44LcHfep2f26OZybMJPN1TTQftibvQEl3CWeOmJrzqGbFxOA000QXDWO9WJaOQpA==", "dev": true, "requires": { - "@types/estree": "*", - "@types/node": "*", - "acorn": "^7.1.0" + "fsevents": "~2.1.2" } }, "rollup-plugin-typescript2": { - "version": "0.25.3", - "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.25.3.tgz", - "integrity": "sha512-ADkSaidKBovJmf5VBnZBZe+WzaZwofuvYdzGAKTN/J4hN7QJCFYAq7IrH9caxlru6T5qhX41PNFS1S4HqhsGQg==", + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/rollup-plugin-typescript2/-/rollup-plugin-typescript2-0.26.0.tgz", + "integrity": "sha512-lUK7XZVG77tu8dmv1L/0LZFlavED/5Yo6e4iMMl6fdox/yKdj4IFRRPPJEXNdmEaT1nDQQeCi7b5IwKHffMNeg==", "dev": true, "requires": { - "find-cache-dir": "^3.0.0", + "find-cache-dir": "^3.2.0", "fs-extra": "8.1.0", - "resolve": "1.12.0", - "rollup-pluginutils": "2.8.1", + "resolve": "1.15.1", + "rollup-pluginutils": "2.8.2", "tslib": "1.10.0" }, "dependencies": { "find-cache-dir": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.2.0.tgz", - "integrity": "sha512-1JKclkYYsf1q9WIJKLZa9S9muC+08RIjzAlLrK4QcYLJMS6mk9yombQ9qf+zJ7H9LS800k0s44L4sDq9VYzqyg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", "dev": true, "requires": { "commondir": "^1.0.1", - "make-dir": "^3.0.0", + "make-dir": "^3.0.2", "pkg-dir": "^4.1.0" } }, @@ -2001,9 +3102,9 @@ } }, "make-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.0.tgz", - "integrity": "sha512-grNJDhb8b1Jm1qeqW5R/O63wUo4UXo2v2HMic6YT9i/HBlF93S8jkMgH7yugvY9ABDShH4VZMn8I+U8+fCNegw==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.0.2.tgz", + "integrity": "sha512-rYKABKutXa6vXTXhoV18cBE7PaewPXHe/Bdq4v+ZLMhxbWApkFFplT0LcbMW+6BbjnQXzZ/sAvSE/JdguApG5w==", "dev": true, "requires": { "semver": "^6.0.0" @@ -2034,9 +3135,9 @@ } }, "resolve": { - "version": "1.12.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.0.tgz", - "integrity": "sha512-B/dOmuoAik5bKcD6s6nXDCjzUKnaDvdkRyAk6rsmsKLipWj4797iothd7jmmUhWTfinVMU+wc56rYKsit2Qy4w==", + "version": "1.15.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.15.1.tgz", + "integrity": "sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==", "dev": true, "requires": { "path-parse": "^1.0.6" @@ -2057,14 +3158,32 @@ } }, "rollup-pluginutils": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.1.tgz", - "integrity": "sha512-J5oAoysWar6GuZo0s+3bZ6sVZAC0pfqKz68De7ZgDi5z63jOVZn1uJL/+z1jeKHNbGII8kAyHF5q8LnxSX5lQg==", + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-2.8.2.tgz", + "integrity": "sha512-EEp9NhnUkwY8aif6bxgovPHMoMoNr2FulJziTndpt5H9RdwC47GSGuII9XxpSdzVGM0GWrNPHV6ie1LTNJPaLQ==", "dev": true, "requires": { "estree-walker": "^0.6.1" } }, + "run-async": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.0.tgz", + "integrity": "sha512-xJTbh/d7Lm7SBhc1tNvTpeCHaEzoyxPrqNlvSdMfBTYwaY++UJFyXUOxAtsRUXjlqOfj8luNaR9vjCh4KeV+pg==", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.4", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", + "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, "safe-buffer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", @@ -2110,6 +3229,17 @@ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", "dev": true }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -2280,6 +3410,46 @@ "has-flag": "^3.0.0" } }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, "test-exclude": { "version": "5.2.3", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-5.2.3.tgz", @@ -2292,12 +3462,42 @@ "require-main-filename": "^2.0.0" } }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", "dev": true }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, "tough-cookie": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", @@ -2348,39 +3548,10 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==" }, - "tslint": { - "version": "5.20.1", - "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.20.1.tgz", - "integrity": "sha512-EcMxhzCFt8k+/UP5r8waCf/lzmeSyVlqxqMEDQE7rWYiQky8KpIBz1JAoYXfROHrPZ1XXd43q8yQnULOLiBRQg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "builtin-modules": "^1.1.1", - "chalk": "^2.3.0", - "commander": "^2.12.1", - "diff": "^4.0.1", - "glob": "^7.1.1", - "js-yaml": "^3.13.1", - "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", - "resolve": "^1.3.2", - "semver": "^5.3.0", - "tslib": "^1.8.0", - "tsutils": "^2.29.0" - }, - "dependencies": { - "diff": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.1.tgz", - "integrity": "sha512-s2+XdvhPCOF01LRQBC8hf4vhbVmI2CGS5aZnxLJlT5FtdhPCDFq80q++zK2KlrVorVDdL5BOGZ/VfLrVtYNF+Q==", - "dev": true - } - } - }, "tsutils": { - "version": "2.29.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", - "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "version": "3.17.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz", + "integrity": "sha512-kzeQ5B8H3w60nFY2g8cJIuH7JDpsALXySGtwGJ0p2LSjLgay3NdIpqq5SoOBe46bKDW2iq25irHCr8wjomUS2g==", "dev": true, "requires": { "tslib": "^1.8.1" @@ -2401,6 +3572,21 @@ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + }, "typescript": { "version": "3.8.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.3.tgz", @@ -2455,6 +3641,12 @@ "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==", "dev": true }, + "v8-compile-cache": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", + "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", + "dev": true + }, "validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -2509,6 +3701,12 @@ "string-width": "^1.0.2 || 2" } }, + "word-wrap": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "dev": true + }, "wordwrap": { "version": "0.0.3", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", @@ -2568,6 +3766,15 @@ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", "dev": true }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, "write-file-atomic": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.3.tgz", diff --git a/package.json b/package.json index 79663c2..27bce74 100644 --- a/package.json +++ b/package.json @@ -18,8 +18,8 @@ "clear": "rimraf build/*", "rebuild": "npm run clear && npm run build", "build:module": "rollup -c", - "lint": "tslint -p .", - "lint:fix": "tslint --fix -p .", + "lint": "eslint . --ext .ts", + "lint:fix": "eslint --fix . --ext .ts", "prepub": "npm run lint && npm run rebuild", "pub": "npm version patch && npm publish", "postpub": "git push && git push --tags origin master", @@ -47,18 +47,21 @@ "url": "https://github.com/PeculiarVentures/webcrypto/issues" }, "homepage": "https://github.com/PeculiarVentures/webcrypto#readme", - "banner": "// Copyright (c) 2019, Peculiar Ventures, All rights reserved.", + "banner": "// Copyright (c) 2020, Peculiar Ventures, All rights reserved.", "devDependencies": { - "@types/mocha": "^5.2.7", - "@types/node": "^12.12.29", + "@types/mocha": "^7.0.2", + "@types/node": "^12.12.30", + "@typescript-eslint/eslint-plugin": "^2.23.0", + "@typescript-eslint/parser": "^2.23.0", "coveralls": "^3.0.9", - "mocha": "^6.2.2", + "eslint": "^6.8.0", + "eslint-plugin-import": "^2.20.1", + "mocha": "^7.1.0", "nyc": "^14.1.1", "rimraf": "^3.0.2", - "rollup": "^1.32.1", - "rollup-plugin-typescript2": "^0.25.3", + "rollup": "^2.0.6", + "rollup-plugin-typescript2": "^0.26.0", "ts-node": "^8.6.2", - "tslint": "^5.20.1", "typescript": "^3.8.3" }, "dependencies": { @@ -87,5 +90,10 @@ }, "engines": { "node": ">=10.12.0" + }, + "mocha": { + "require": "ts-node/register", + "extension": ["ts"], + "files": "test/**/*.ts" } -} +} \ No newline at end of file diff --git a/src/asn/ec_private_key.ts b/src/asn/ec_private_key.ts index a13f222..dd0a2b7 100644 --- a/src/asn/ec_private_key.ts +++ b/src/asn/ec_private_key.ts @@ -1,4 +1,4 @@ -import { AsnIntegerConverter, AsnParser, AsnProp, AsnPropTypes, AsnSerializer, IAsnConverter } from "@peculiar/asn1-schema"; +import { AsnIntegerConverter, AsnProp, AsnPropTypes, AsnSerializer } from "@peculiar/asn1-schema"; import { IJsonConvertible } from "@peculiar/json-schema"; import { Convert } from "pvtsutils"; import { EcPublicKey } from "./ec_public_key"; diff --git a/src/asn/ec_signature.ts b/src/asn/ec_signature.ts index 2a25932..311d3c6 100644 --- a/src/asn/ec_signature.ts +++ b/src/asn/ec_signature.ts @@ -1,4 +1,4 @@ -import { AsnIntegerArrayBufferConverter, AsnProp, AsnPropTypes, IAsnConverter } from "@peculiar/asn1-schema"; +import { AsnProp, AsnPropTypes, IAsnConverter } from "@peculiar/asn1-schema"; // @ts-ignore import * as asn1 from "asn1js"; diff --git a/src/index.ts b/src/index.ts index c3f9d3d..2be3353 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,2 +1,2 @@ -export { CryptoKey } from "./keys"; +export { CryptoKey } from "webcrypto-core"; export { Crypto } from "./crypto"; diff --git a/src/keys/key.ts b/src/keys/key.ts index 24eef4a..c8fd240 100644 --- a/src/keys/key.ts +++ b/src/keys/key.ts @@ -7,7 +7,7 @@ export class CryptoKey extends core.CryptoKey { public algorithm: KeyAlgorithm = { name: "" }; @JsonProp({ name: "ext", type: JsonPropTypes.Boolean, optional: true }) - public extractable: boolean = false; + public extractable = false; public type: KeyType = "secret"; @@ -15,8 +15,8 @@ export class CryptoKey extends core.CryptoKey { public usages: KeyUsage[] = []; @JsonProp({ type: JsonPropTypes.String }) - protected kty: string = "oct"; + protected kty = "oct"; @JsonProp({ type: JsonPropTypes.String }) - protected alg: string = ""; + protected alg = ""; } diff --git a/src/mechs/aes/aes_cbc.ts b/src/mechs/aes/aes_cbc.ts index f145cf3..12777cd 100644 --- a/src/mechs/aes/aes_cbc.ts +++ b/src/mechs/aes/aes_cbc.ts @@ -1,4 +1,5 @@ import * as core from "webcrypto-core"; +import { getCryptoKey, setCryptoKey } from "../storage"; import { AesCrypto } from "./crypto"; import { AesCryptoKey } from "./key"; @@ -13,28 +14,29 @@ export class AesCbcProvider extends core.AesCbcProvider { extractable, keyUsages); - return key; + return setCryptoKey(key); } public async onEncrypt(algorithm: Algorithm, key: AesCryptoKey, data: ArrayBuffer): Promise { - return AesCrypto.encrypt(algorithm, key, new Uint8Array(data)); + return AesCrypto.encrypt(algorithm, getCryptoKey(key) as AesCryptoKey, new Uint8Array(data)); } public async onDecrypt(algorithm: Algorithm, key: AesCryptoKey, data: ArrayBuffer): Promise { - return AesCrypto.decrypt(algorithm, key, new Uint8Array(data)); + return AesCrypto.decrypt(algorithm, getCryptoKey(key) as AesCryptoKey, new Uint8Array(data)); } public async onExportKey(format: KeyFormat, key: AesCryptoKey): Promise { - return AesCrypto.exportKey(format, key); + return AesCrypto.exportKey(format, getCryptoKey(key) as AesCryptoKey); } public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: Algorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise { - return AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages); + const key = await AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages); + return setCryptoKey(key); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof AesCryptoKey)) { + if (!(getCryptoKey(key) instanceof AesCryptoKey)) { throw new TypeError("key: Is not a AesCryptoKey"); } } diff --git a/src/mechs/aes/aes_cmac.ts b/src/mechs/aes/aes_cmac.ts index 1053773..e1afef7 100644 --- a/src/mechs/aes/aes_cmac.ts +++ b/src/mechs/aes/aes_cmac.ts @@ -1,5 +1,6 @@ import * as crypto from "crypto"; import * as core from "webcrypto-core"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { AesCrypto } from "./crypto"; import { AesCryptoKey } from "./key"; @@ -34,6 +35,35 @@ function xor(a: Buffer, b: Buffer) { return output; } +function aes(key: Buffer, message: Buffer) { + const cipher = crypto.createCipheriv(`aes${key.length << 3}`, key, zero); + const result = cipher.update(message); + cipher.final(); + return result; +} + +function getMessageBlock(message: Buffer, blockIndex: number) { + const block = Buffer.alloc(blockSize); + const start = blockIndex * blockSize; + const end = start + blockSize; + + message.copy(block, 0, start, end); + + return block; +} + +function getPaddedMessageBlock(message: Buffer, blockIndex: number) { + const block = Buffer.alloc(blockSize); + const start = blockIndex * blockSize; + const end = message.length; + + block.fill(0); + message.copy(block, 0, start, end); + block[end - start] = 0x80; + + return block; +} + function generateSubkeys(key: Buffer) { const l = aes(key, zero); @@ -50,19 +80,11 @@ function generateSubkeys(key: Buffer) { return { subkey1, subkey2 }; } -function aes(key: Buffer, message: Buffer) { - const cipher = crypto.createCipheriv(`aes${key.length << 3}`, key, zero); - const result = cipher.update(message); - cipher.final(); - return result; -} - function aesCmac(key: Buffer, message: Buffer) { const subkeys = generateSubkeys(key); let blockCount = Math.ceil(message.length / blockSize); let lastBlockCompleteFlag: boolean; let lastBlock: Buffer; - let lastBlockIndex: number; if (blockCount === 0) { blockCount = 1; @@ -70,7 +92,7 @@ function aesCmac(key: Buffer, message: Buffer) { } else { lastBlockCompleteFlag = (message.length % blockSize === 0); } - lastBlockIndex = blockCount - 1; + const lastBlockIndex = blockCount - 1; if (lastBlockCompleteFlag) { lastBlock = xor(getMessageBlock(message, lastBlockIndex), subkeys.subkey1); @@ -89,28 +111,6 @@ function aesCmac(key: Buffer, message: Buffer) { return aes(key, y); } -function getMessageBlock(message: Buffer, blockIndex: number) { - const block = new Buffer(blockSize); - const start = blockIndex * blockSize; - const end = start + blockSize; - - message.copy(block, 0, start, end); - - return block; -} - -function getPaddedMessageBlock(message: Buffer, blockIndex: number) { - const block = new Buffer(blockSize); - const start = blockIndex * blockSize; - const end = message.length; - - block.fill(0); - message.copy(block, 0, start, end); - block[end - start] = 0x80; - - return block; -} - export class AesCmacProvider extends core.AesCmacProvider { public async onGenerateKey(algorithm: AesKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { @@ -122,11 +122,11 @@ export class AesCmacProvider extends core.AesCmacProvider { extractable, keyUsages); - return key; + return setCryptoKey(key); } public async onSign(algorithm: AesCmacParams, key: AesCryptoKey, data: ArrayBuffer): Promise { - const result = aesCmac(key.data, Buffer.from(data)); + const result = aesCmac(getCryptoKey(key).data, Buffer.from(data)); return new Uint8Array(result).buffer; } @@ -136,16 +136,17 @@ export class AesCmacProvider extends core.AesCmacProvider { } public async onExportKey(format: KeyFormat, key: AesCryptoKey): Promise { - return AesCrypto.exportKey(format, key); + return AesCrypto.exportKey(format, getCryptoKey(key) as AesCryptoKey); } public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: Algorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise { - return AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages); + const res = await AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages); + return setCryptoKey(res); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof AesCryptoKey)) { + if (!(getCryptoKey(key) instanceof AesCryptoKey)) { throw new TypeError("key: Is not a AesCryptoKey"); } } diff --git a/src/mechs/aes/aes_ctr.ts b/src/mechs/aes/aes_ctr.ts index d2cd221..50af5fa 100644 --- a/src/mechs/aes/aes_ctr.ts +++ b/src/mechs/aes/aes_ctr.ts @@ -1,4 +1,5 @@ import * as core from "webcrypto-core"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { AesCrypto } from "./crypto"; import { AesCryptoKey } from "./key"; @@ -13,28 +14,29 @@ export class AesCtrProvider extends core.AesCtrProvider { extractable, keyUsages); - return key; + return setCryptoKey(key); } public async onEncrypt(algorithm: AesCtrParams, key: AesCryptoKey, data: ArrayBuffer): Promise { - return AesCrypto.encrypt(algorithm, key, new Uint8Array(data)); + return AesCrypto.encrypt(algorithm, getCryptoKey(key) as AesCryptoKey, new Uint8Array(data)); } public async onDecrypt(algorithm: AesCtrParams, key: AesCryptoKey, data: ArrayBuffer): Promise { - return AesCrypto.decrypt(algorithm, key, new Uint8Array(data)); + return AesCrypto.decrypt(algorithm, getCryptoKey(key) as AesCryptoKey, new Uint8Array(data)); } public async onExportKey(format: KeyFormat, key: AesCryptoKey): Promise { - return AesCrypto.exportKey(format, key); + return AesCrypto.exportKey(format, getCryptoKey(key) as AesCryptoKey); } public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: Algorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise { - return AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages); + const res = await AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages); + return setCryptoKey(res); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof AesCryptoKey)) { + if (!(getCryptoKey(key) instanceof AesCryptoKey)) { throw new TypeError("key: Is not a AesCryptoKey"); } } diff --git a/src/mechs/aes/aes_ecb.ts b/src/mechs/aes/aes_ecb.ts index 68e023d..a5a49de 100644 --- a/src/mechs/aes/aes_ecb.ts +++ b/src/mechs/aes/aes_ecb.ts @@ -1,4 +1,5 @@ import * as core from "webcrypto-core"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { AesCrypto } from "./crypto"; import { AesCryptoKey } from "./key"; @@ -13,28 +14,29 @@ export class AesEcbProvider extends core.AesEcbProvider { extractable, keyUsages); - return key; + return setCryptoKey(key); } public async onEncrypt(algorithm: Algorithm, key: AesCryptoKey, data: ArrayBuffer): Promise { - return AesCrypto.encrypt(algorithm, key, new Uint8Array(data)); + return AesCrypto.encrypt(algorithm, getCryptoKey(key) as AesCryptoKey, new Uint8Array(data)); } public async onDecrypt(algorithm: Algorithm, key: AesCryptoKey, data: ArrayBuffer): Promise { - return AesCrypto.decrypt(algorithm, key, new Uint8Array(data)); + return AesCrypto.decrypt(algorithm, getCryptoKey(key) as AesCryptoKey, new Uint8Array(data)); } public async onExportKey(format: KeyFormat, key: AesCryptoKey): Promise { - return AesCrypto.exportKey(format, key); + return AesCrypto.exportKey(format, getCryptoKey(key) as AesCryptoKey); } public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: Algorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise { - return AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages); + const res = await AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages); + return setCryptoKey(res); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof AesCryptoKey)) { + if (!(getCryptoKey(key) instanceof AesCryptoKey)) { throw new TypeError("key: Is not a AesCryptoKey"); } } diff --git a/src/mechs/aes/aes_gcm.ts b/src/mechs/aes/aes_gcm.ts index defb8f4..b2d61ba 100644 --- a/src/mechs/aes/aes_gcm.ts +++ b/src/mechs/aes/aes_gcm.ts @@ -1,4 +1,5 @@ import * as core from "webcrypto-core"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { AesCrypto } from "./crypto"; import { AesCryptoKey } from "./key"; @@ -13,28 +14,29 @@ export class AesGcmProvider extends core.AesGcmProvider { extractable, keyUsages); - return key; + return setCryptoKey(key); } public async onEncrypt(algorithm: AesGcmParams, key: AesCryptoKey, data: ArrayBuffer): Promise { - return AesCrypto.encrypt(algorithm, key, new Uint8Array(data)); + return AesCrypto.encrypt(algorithm, getCryptoKey(key) as AesCryptoKey, new Uint8Array(data)); } public async onDecrypt(algorithm: AesGcmParams, key: AesCryptoKey, data: ArrayBuffer): Promise { - return AesCrypto.decrypt(algorithm, key, new Uint8Array(data)); + return AesCrypto.decrypt(algorithm, getCryptoKey(key) as AesCryptoKey, new Uint8Array(data)); } public async onExportKey(format: KeyFormat, key: AesCryptoKey): Promise { - return AesCrypto.exportKey(format, key); + return AesCrypto.exportKey(format, getCryptoKey(key) as AesCryptoKey); } public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: Algorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise { - return AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages); + const res = await AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages); + return setCryptoKey(res); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof AesCryptoKey)) { + if (!(getCryptoKey(key) instanceof AesCryptoKey)) { throw new TypeError("key: Is not a AesCryptoKey"); } } diff --git a/src/mechs/aes/aes_kw.ts b/src/mechs/aes/aes_kw.ts index 527ebd9..b70a027 100644 --- a/src/mechs/aes/aes_kw.ts +++ b/src/mechs/aes/aes_kw.ts @@ -1,11 +1,12 @@ import * as core from "webcrypto-core"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { AesCrypto } from "./crypto"; import { AesCryptoKey } from "./key"; export class AesKwProvider extends core.AesKwProvider { public async onGenerateKey(algorithm: AesKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { - return await AesCrypto.generateKey( + const res = await AesCrypto.generateKey( { name: this.name, length: algorithm.length, @@ -13,27 +14,29 @@ export class AesKwProvider extends core.AesKwProvider { extractable, keyUsages, ); + return setCryptoKey(res); } public async onExportKey(format: KeyFormat, key: AesCryptoKey): Promise { - return AesCrypto.exportKey(format, key); + return AesCrypto.exportKey(format, getCryptoKey(key) as AesCryptoKey); } public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: Algorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise { - return AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages); + const res = await AesCrypto.importKey(format, keyData, { name: algorithm.name }, extractable, keyUsages); + return setCryptoKey(res); } public async onEncrypt(algorithm: Algorithm, key: AesCryptoKey, data: ArrayBuffer): Promise { - return AesCrypto.encrypt(algorithm, key, new Uint8Array(data)); + return AesCrypto.encrypt(algorithm, getCryptoKey(key) as AesCryptoKey, new Uint8Array(data)); } public async onDecrypt(algorithm: Algorithm, key: AesCryptoKey, data: ArrayBuffer): Promise { - return AesCrypto.decrypt(algorithm, key, new Uint8Array(data)); + return AesCrypto.decrypt(algorithm, getCryptoKey(key) as AesCryptoKey, new Uint8Array(data)); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof AesCryptoKey)) { + if (!(getCryptoKey(key) instanceof AesCryptoKey)) { throw new TypeError("key: Is not a AesCryptoKey"); } } diff --git a/src/mechs/aes/crypto.ts b/src/mechs/aes/crypto.ts index 70f41cc..090ef37 100644 --- a/src/mechs/aes/crypto.ts +++ b/src/mechs/aes/crypto.ts @@ -1,11 +1,9 @@ -import { JsonParser, JsonSerializer } from "@peculiar/json-schema"; import crypto, { CipherGCM, DecipherGCM } from "crypto"; +import { JsonParser, JsonSerializer } from "@peculiar/json-schema"; import * as core from "webcrypto-core"; import { CryptoKey } from "../../keys"; import { AesCryptoKey } from "./key"; -const WRONG_KEY_TYPE = `Key must be instance of ${AesCryptoKey.name}`; - export class AesCrypto { public static AES_KW_IV = Buffer.from("A6A6A6A6A6A6A6A6", "hex"); diff --git a/src/mechs/des/crypto.ts b/src/mechs/des/crypto.ts index ce049c6..5b0fc90 100644 --- a/src/mechs/des/crypto.ts +++ b/src/mechs/des/crypto.ts @@ -1,5 +1,5 @@ -import { JsonParser, JsonSerializer } from "@peculiar/json-schema"; import crypto from "crypto"; +import { JsonParser, JsonSerializer } from "@peculiar/json-schema"; import * as core from "webcrypto-core"; import { DesParams } from "webcrypto-core"; import { CryptoKey } from "../../keys"; diff --git a/src/mechs/des/des_cbc.ts b/src/mechs/des/des_cbc.ts index af9d7fa..92f075b 100644 --- a/src/mechs/des/des_cbc.ts +++ b/src/mechs/des/des_cbc.ts @@ -1,5 +1,6 @@ import * as core from "webcrypto-core"; import { CryptoKey } from "../../keys"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { DesCrypto } from "./crypto"; import { DesCryptoKey } from "./key"; @@ -11,7 +12,7 @@ export class DesCbcProvider extends core.DesProvider { public ivSize = 8; public name = "DES-CBC"; - public async onGenerateKey(algorithm: core.DesKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { + public async onGenerateKey(algorithm: core.DesKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { const key = await DesCrypto.generateKey( { name: this.name, @@ -20,32 +21,32 @@ export class DesCbcProvider extends core.DesProvider { extractable, keyUsages); - return key; + return setCryptoKey(key); } public async onEncrypt(algorithm: DesCbcParams, key: DesCryptoKey, data: ArrayBuffer): Promise { - return DesCrypto.encrypt(algorithm, key, new Uint8Array(data)); + return DesCrypto.encrypt(algorithm, getCryptoKey(key) as DesCryptoKey, new Uint8Array(data)); } public async onDecrypt(algorithm: DesCbcParams, key: DesCryptoKey, data: ArrayBuffer): Promise { - return DesCrypto.decrypt(algorithm, key, new Uint8Array(data)); + return DesCrypto.decrypt(algorithm, getCryptoKey(key) as DesCryptoKey, new Uint8Array(data)); } public async onExportKey(format: KeyFormat, key: CryptoKey): Promise { - return DesCrypto.exportKey(format, key); + return DesCrypto.exportKey(format, getCryptoKey(key) as DesCryptoKey); } - public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: Algorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise { + public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: Algorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise { const key = await DesCrypto.importKey(format, keyData, { name: this.name, length: this.keySizeBits }, extractable, keyUsages); if (key.data.length !== (this.keySizeBits >> 3)) { throw new core.OperationError("keyData: Wrong key size"); } - return key; + return setCryptoKey(key); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof DesCryptoKey)) { + if (!(getCryptoKey(key) instanceof DesCryptoKey)) { throw new TypeError("key: Is not a DesCryptoKey"); } } diff --git a/src/mechs/des/des_ede3_cbc.ts b/src/mechs/des/des_ede3_cbc.ts index b35522f..7f94c61 100644 --- a/src/mechs/des/des_ede3_cbc.ts +++ b/src/mechs/des/des_ede3_cbc.ts @@ -1,5 +1,6 @@ import * as core from "webcrypto-core"; import { CryptoKey } from "../../keys"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { DesCrypto } from "./crypto"; import { DesCryptoKey } from "./key"; @@ -11,7 +12,7 @@ export class DesEde3CbcProvider extends core.DesProvider { public ivSize = 8; public name = "DES-EDE3-CBC"; - public async onGenerateKey(algorithm: core.DesKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { + public async onGenerateKey(algorithm: core.DesKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { const key = await DesCrypto.generateKey( { name: this.name, @@ -20,32 +21,32 @@ export class DesEde3CbcProvider extends core.DesProvider { extractable, keyUsages); - return key; + return setCryptoKey(key); } public async onEncrypt(algorithm: DesEde3CbcParams, key: DesCryptoKey, data: ArrayBuffer): Promise { - return DesCrypto.encrypt(algorithm, key, new Uint8Array(data)); + return DesCrypto.encrypt(algorithm, getCryptoKey(key) as DesCryptoKey, new Uint8Array(data)); } public async onDecrypt(algorithm: DesEde3CbcParams, key: DesCryptoKey, data: ArrayBuffer): Promise { - return DesCrypto.decrypt(algorithm, key, new Uint8Array(data)); + return DesCrypto.decrypt(algorithm, getCryptoKey(key) as DesCryptoKey, new Uint8Array(data)); } public async onExportKey(format: KeyFormat, key: CryptoKey): Promise { - return DesCrypto.exportKey(format, key); + return DesCrypto.exportKey(format, getCryptoKey(key) as DesCryptoKey); } - public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: Algorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise { + public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: Algorithm, extractable: boolean, keyUsages: KeyUsage[]): Promise { const key = await DesCrypto.importKey(format, keyData, { name: this.name, length: this.keySizeBits }, extractable, keyUsages); if (key.data.length !== (this.keySizeBits >> 3)) { throw new core.OperationError("keyData: Wrong key size"); } - return key; + return setCryptoKey(key); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof DesCryptoKey)) { + if (!(getCryptoKey(key) instanceof DesCryptoKey)) { throw new TypeError("key: Is not a DesCryptoKey"); } } diff --git a/src/mechs/ec/crypto.ts b/src/mechs/ec/crypto.ts index bb98b1a..25d55f2 100644 --- a/src/mechs/ec/crypto.ts +++ b/src/mechs/ec/crypto.ts @@ -1,6 +1,6 @@ +import crypto from "crypto"; import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema"; import { JsonParser, JsonSerializer } from "@peculiar/json-schema"; -import crypto from "crypto"; import * as core from "webcrypto-core"; import * as asn from "../../asn"; import { ObjectIdentifier } from "../../asn"; @@ -116,9 +116,10 @@ export class EcCrypto { case "pkcs8": case "spki": return new Uint8Array(key.data).buffer; - case "raw": + case "raw": { const publicKeyInfo = AsnParser.parse(key.data, asn.PublicKeyInfo); return publicKeyInfo.publicKey; + } default: throw new core.OperationError("format: Must be 'jwk', 'raw', pkcs8' or 'spki'"); } @@ -126,7 +127,7 @@ export class EcCrypto { public static async importKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: EcKeyImportParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { switch (format.toLowerCase()) { - case "jwk": + case "jwk": { const jwk = keyData as JsonWebKey; if (jwk.d) { const asnKey = JsonParser.fromJSON(keyData, { targetSchema: asn.EcPrivateKey }); @@ -135,6 +136,7 @@ export class EcCrypto { const asnKey = JsonParser.fromJSON(keyData, { targetSchema: asn.EcPublicKey }); return this.importPublicKey(asnKey, algorithm, extractable, keyUsages); } + } case "raw": { const asnKey = new asn.EcPublicKey(keyData as ArrayBuffer); return this.importPublicKey(asnKey, algorithm, extractable, keyUsages); diff --git a/src/mechs/ec/ec_dh.ts b/src/mechs/ec/ec_dh.ts index 501e1d8..496b121 100644 --- a/src/mechs/ec/ec_dh.ts +++ b/src/mechs/ec/ec_dh.ts @@ -1,5 +1,6 @@ import * as core from "webcrypto-core"; import { CryptoKey } from "../../keys"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { EcCrypto } from "./crypto"; import { EcPrivateKey } from "./private_key"; import { EcPublicKey } from "./public_key"; @@ -7,7 +8,7 @@ import { EcPublicKey } from "./public_key"; export class EcdhProvider extends core.EcdhProvider { public async onGenerateKey(algorithm: EcKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { - const key = await EcCrypto.generateKey( + const keys = await EcCrypto.generateKey( { ...algorithm, name: this.name, @@ -15,27 +16,31 @@ export class EcdhProvider extends core.EcdhProvider { extractable, keyUsages); - return key; + return { + privateKey: setCryptoKey(keys.privateKey as CryptoKey), + publicKey: setCryptoKey(keys.publicKey as CryptoKey), + }; } public async onExportKey(format: KeyFormat, key: CryptoKey): Promise { - return EcCrypto.exportKey(format, key); + return EcCrypto.exportKey(format, getCryptoKey(key)); } - public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: EcKeyImportParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { + public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: EcKeyImportParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { const key = await EcCrypto.importKey(format, keyData, {...algorithm, name: this.name}, extractable, keyUsages); - return key; + return setCryptoKey(key); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof EcPrivateKey || key instanceof EcPublicKey)) { + const internalKey = getCryptoKey(key); + if (!(internalKey instanceof EcPrivateKey || internalKey instanceof EcPublicKey)) { throw new TypeError("key: Is not EC CryptoKey"); } } public async onDeriveBits(algorithm: EcdhKeyDeriveParams, baseKey: CryptoKey, length: number): Promise { - const bits = await EcCrypto.deriveBits(algorithm, baseKey, length); + const bits = await EcCrypto.deriveBits({...algorithm, public: getCryptoKey(algorithm.public)}, getCryptoKey(baseKey), length); return bits; } diff --git a/src/mechs/ec/ec_dsa.ts b/src/mechs/ec/ec_dsa.ts index 89a1a4e..883ea91 100644 --- a/src/mechs/ec/ec_dsa.ts +++ b/src/mechs/ec/ec_dsa.ts @@ -1,5 +1,5 @@ import * as core from "webcrypto-core"; -import { CryptoKey } from "../../keys"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { EcCrypto } from "./crypto"; import { EcPrivateKey } from "./private_key"; import { EcPublicKey } from "./public_key"; @@ -9,7 +9,7 @@ export class EcdsaProvider extends core.EcdsaProvider { public namedCurves = ["P-256", "P-384", "P-521", "K-256"]; public async onGenerateKey(algorithm: EcKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { - const key = await EcCrypto.generateKey( + const keys = await EcCrypto.generateKey( { ...algorithm, name: this.name, @@ -17,29 +17,33 @@ export class EcdsaProvider extends core.EcdsaProvider { extractable, keyUsages); - return key; + return { + privateKey: setCryptoKey(keys.privateKey as EcPrivateKey), + publicKey: setCryptoKey(keys.publicKey as EcPublicKey), + }; } public async onSign(algorithm: EcdsaParams, key: EcPrivateKey, data: ArrayBuffer): Promise { - return EcCrypto.sign(algorithm, key, new Uint8Array(data)); + return EcCrypto.sign(algorithm, getCryptoKey(key) as EcPrivateKey, new Uint8Array(data)); } public async onVerify(algorithm: EcdsaParams, key: EcPublicKey, signature: ArrayBuffer, data: ArrayBuffer): Promise { - return EcCrypto.verify(algorithm, key, new Uint8Array(signature), new Uint8Array(data)); + return EcCrypto.verify(algorithm, getCryptoKey(key) as EcPublicKey, new Uint8Array(signature), new Uint8Array(data)); } public async onExportKey(format: KeyFormat, key: CryptoKey): Promise { - return EcCrypto.exportKey(format, key); + return EcCrypto.exportKey(format, getCryptoKey(key)); } public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: EcKeyImportParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { const key = await EcCrypto.importKey(format, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); - return key; + return setCryptoKey(key); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof EcPrivateKey || key instanceof EcPublicKey)) { + const internalKey = getCryptoKey(key); + if (!(internalKey instanceof EcPrivateKey || internalKey instanceof EcPublicKey)) { throw new TypeError("key: Is not EC CryptoKey"); } } diff --git a/src/mechs/ec/private_key.ts b/src/mechs/ec/private_key.ts index 49eb197..70d00fb 100644 --- a/src/mechs/ec/private_key.ts +++ b/src/mechs/ec/private_key.ts @@ -29,14 +29,14 @@ export class EcPrivateKey extends AsymmetricKey implements IJsonConvertible { } public fromJSON(json: JsonWebKey) { - if (!json.alg) { - throw new core.OperationError(`Cannot get named curve from JWK. Property 'alg' is required`); + if (!json.crv) { + throw new core.OperationError(`Cannot get named curve from JWK. Property 'crv' is required`); } const keyInfo = new asn.PrivateKeyInfo(); keyInfo.privateKeyAlgorithm.algorithm = "1.2.840.10045.2.1"; keyInfo.privateKeyAlgorithm.parameters = AsnSerializer.serialize( - new ObjectIdentifier(getOidByNamedCurve(json.crv!)), + new ObjectIdentifier(getOidByNamedCurve(json.crv)), ); const key = JsonParser.fromJSON(json, { targetSchema: asn.EcPrivateKey }); keyInfo.privateKey = AsnSerializer.serialize(key); diff --git a/src/mechs/ec/public_key.ts b/src/mechs/ec/public_key.ts index 88c85d6..f6ac14e 100644 --- a/src/mechs/ec/public_key.ts +++ b/src/mechs/ec/public_key.ts @@ -1,5 +1,6 @@ import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema"; import { IJsonConvertible, JsonParser, JsonSerializer } from "@peculiar/json-schema"; +import * as core from "webcrypto-core"; import * as asn from "../../asn"; import { ObjectIdentifier } from "../../asn"; import { AsymmetricKey } from "../../keys/asymmetric"; @@ -29,12 +30,16 @@ export class EcPublicKey extends AsymmetricKey implements IJsonConvertible { } public fromJSON(json: JsonWebKey) { + if (!json.crv) { + throw new core.OperationError(`Cannot get named curve from JWK. Property 'crv' is required`); + } + const key = JsonParser.fromJSON(json, { targetSchema: asn.EcPublicKey }); const keyInfo = new asn.PublicKeyInfo(); keyInfo.publicKeyAlgorithm.algorithm = "1.2.840.10045.2.1"; keyInfo.publicKeyAlgorithm.parameters = AsnSerializer.serialize( - new ObjectIdentifier(getOidByNamedCurve(json.crv!)), + new ObjectIdentifier(getOidByNamedCurve(json.crv)), ); keyInfo.publicKey = AsnSerializer.toASN(key).valueHex; diff --git a/src/mechs/hkdf/hkdf.ts b/src/mechs/hkdf/hkdf.ts index f5cc28d..ca114e8 100644 --- a/src/mechs/hkdf/hkdf.ts +++ b/src/mechs/hkdf/hkdf.ts @@ -1,6 +1,7 @@ import crypto from "crypto"; import * as core from "webcrypto-core"; import { BufferSourceConverter, CryptoKey } from "webcrypto-core"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { HkdfCryptoKey } from "./key"; export class HkdfProvider extends core.HkdfProvider { @@ -15,7 +16,7 @@ export class HkdfProvider extends core.HkdfProvider { key.algorithm = { name: this.name }; key.extractable = extractable; key.usages = keyUsages; - return key; + return setCryptoKey(key); } public async onDeriveBits(params: HkdfParams, baseKey: HkdfCryptoKey, length: number): Promise { @@ -26,7 +27,7 @@ export class HkdfProvider extends core.HkdfProvider { const info = BufferSourceConverter.toUint8Array(params.info); const PRK = crypto.createHmac(hash, BufferSourceConverter.toUint8Array(params.salt)) - .update(BufferSourceConverter.toUint8Array(baseKey.data)) + .update(BufferSourceConverter.toUint8Array(getCryptoKey(baseKey).data)) .digest(); const blocks = [Buffer.alloc(0)]; @@ -44,7 +45,7 @@ export class HkdfProvider extends core.HkdfProvider { public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof HkdfCryptoKey)) { + if (!(getCryptoKey(key) instanceof HkdfCryptoKey)) { throw new TypeError("key: Is not HKDF CryptoKey"); } } diff --git a/src/mechs/hmac/hmac.ts b/src/mechs/hmac/hmac.ts index 6b86c86..4f14730 100644 --- a/src/mechs/hmac/hmac.ts +++ b/src/mechs/hmac/hmac.ts @@ -1,6 +1,7 @@ -import { JsonParser, JsonSerializer } from "@peculiar/json-schema"; import crypto from "crypto"; +import { JsonParser, JsonSerializer } from "@peculiar/json-schema"; import * as core from "webcrypto-core"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { HmacCryptoKey } from "./key"; export class HmacProvider extends core.HmacProvider { @@ -16,12 +17,12 @@ export class HmacProvider extends core.HmacProvider { key.usages = keyUsages; key.data = crypto.randomBytes(length >> 3); - return key; + return setCryptoKey(key); } public async onSign(algorithm: Algorithm, key: HmacCryptoKey, data: ArrayBuffer): Promise { const hash = key.algorithm.hash.name.replace("-", ""); - const hmac = crypto.createHmac(hash, key.data) + const hmac = crypto.createHmac(hash, getCryptoKey(key).data) .update(Buffer.from(data)).digest(); return new Uint8Array(hmac).buffer; @@ -29,7 +30,7 @@ export class HmacProvider extends core.HmacProvider { public async onVerify(algorithm: Algorithm, key: HmacCryptoKey, signature: ArrayBuffer, data: ArrayBuffer): Promise { const hash = key.algorithm.hash.name.replace("-", ""); - const hmac = crypto.createHmac(hash, key.data) + const hmac = crypto.createHmac(hash, getCryptoKey(key).data) .update(Buffer.from(data)).digest(); return hmac.compare(Buffer.from(signature)) === 0; @@ -58,15 +59,15 @@ export class HmacProvider extends core.HmacProvider { key.extractable = extractable; key.usages = keyUsages; - return key; + return setCryptoKey(key); } public async onExportKey(format: KeyFormat, key: HmacCryptoKey): Promise { switch (format.toLowerCase()) { case "jwk": - return JsonSerializer.toJSON(key); + return JsonSerializer.toJSON(getCryptoKey(key)); case "raw": - return new Uint8Array(key.data).buffer; + return new Uint8Array(getCryptoKey(key).data).buffer; default: throw new core.OperationError("format: Must be 'jwk' or 'raw'"); } @@ -74,7 +75,7 @@ export class HmacProvider extends core.HmacProvider { public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof HmacCryptoKey)) { + if (!(getCryptoKey(key) instanceof HmacCryptoKey)) { throw new TypeError("key: Is not HMAC CryptoKey"); } } diff --git a/src/mechs/hmac/key.ts b/src/mechs/hmac/key.ts index dda4bbb..fe4aace 100644 --- a/src/mechs/hmac/key.ts +++ b/src/mechs/hmac/key.ts @@ -1,5 +1,4 @@ import { JsonProp } from "@peculiar/json-schema"; -import * as core from "webcrypto-core"; import { JsonBase64UrlConverter } from "../../converters"; import { CryptoKey } from "../../keys"; diff --git a/src/mechs/pbkdf/key.ts b/src/mechs/pbkdf/key.ts index 0bf0f59..9849979 100644 --- a/src/mechs/pbkdf/key.ts +++ b/src/mechs/pbkdf/key.ts @@ -1,4 +1,3 @@ -import * as core from "webcrypto-core"; import { CryptoKey } from "../../keys"; export class PbkdfCryptoKey extends CryptoKey { diff --git a/src/mechs/pbkdf/pbkdf2.ts b/src/mechs/pbkdf/pbkdf2.ts index ab3cdcb..968e68f 100644 --- a/src/mechs/pbkdf/pbkdf2.ts +++ b/src/mechs/pbkdf/pbkdf2.ts @@ -1,5 +1,6 @@ import crypto from "crypto"; import * as core from "webcrypto-core"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { PbkdfCryptoKey } from "./key"; export class Pbkdf2Provider extends core.Pbkdf2Provider { @@ -8,7 +9,7 @@ export class Pbkdf2Provider extends core.Pbkdf2Provider { return new Promise((resolve, reject) => { const salt = core.BufferSourceConverter.toArrayBuffer(algorithm.salt); const hash = (algorithm.hash as Algorithm).name.replace("-", ""); - crypto.pbkdf2(baseKey.data, Buffer.from(salt), algorithm.iterations, length >> 3, hash, (err, derivedBits) => { + crypto.pbkdf2(getCryptoKey(baseKey).data, Buffer.from(salt), algorithm.iterations, length >> 3, hash, (err, derivedBits) => { if (err) { reject(err); } else { @@ -25,14 +26,14 @@ export class Pbkdf2Provider extends core.Pbkdf2Provider { key.algorithm = { name: this.name }; key.extractable = false; key.usages = keyUsages; - return key; + return setCryptoKey(key); } throw new core.OperationError("format: Must be 'raw'"); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof PbkdfCryptoKey)) { + if (!(getCryptoKey(key) instanceof PbkdfCryptoKey)) { throw new TypeError("key: Is not PBKDF CryptoKey"); } } diff --git a/src/mechs/rsa/crypto.ts b/src/mechs/rsa/crypto.ts index 1ebc2bb..4f33f4f 100644 --- a/src/mechs/rsa/crypto.ts +++ b/src/mechs/rsa/crypto.ts @@ -1,6 +1,6 @@ +import crypto from "crypto"; import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema"; import { JsonParser, JsonSerializer } from "@peculiar/json-schema"; -import crypto from "crypto"; import * as core from "webcrypto-core"; import * as asn from "../../asn"; import { CryptoKey } from "../../keys"; @@ -74,7 +74,7 @@ export class RsaCrypto { public static async importKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: RsaHashedImportParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { switch (format.toLowerCase()) { - case "jwk": + case "jwk": { const jwk = keyData as JsonWebKey; if (jwk.d) { const asnKey = JsonParser.fromJSON(keyData, { targetSchema: asn.RsaPrivateKey }); @@ -83,6 +83,7 @@ export class RsaCrypto { const asnKey = JsonParser.fromJSON(keyData, { targetSchema: asn.RsaPublicKey }); return this.importPublicKey(asnKey, algorithm, extractable, keyUsages); } + } case "spki": { const keyInfo = AsnParser.parse(new Uint8Array(keyData as ArrayBuffer), asn.PublicKeyInfo); const asnKey = AsnParser.parse(keyInfo.publicKey, asn.RsaPublicKey); diff --git a/src/mechs/rsa/helper.ts b/src/mechs/rsa/helper.ts index 5b374f2..6691b4c 100644 --- a/src/mechs/rsa/helper.ts +++ b/src/mechs/rsa/helper.ts @@ -1,10 +1,12 @@ +/* eslint-disable @typescript-eslint/no-non-null-assertion */ import * as core from "webcrypto-core"; export function getJwkAlgorithm(algorithm: RsaHashedKeyAlgorithm) { switch (algorithm.name.toUpperCase()) { - case "RSA-OAEP": + case "RSA-OAEP": { const mdSize = /(\d+)$/.exec(algorithm.hash.name)![1]; return `RSA-OAEP${mdSize !== "1" ? `-${mdSize}` : ""}`; + } case "RSASSA-PKCS1-V1_5": return `RS${/(\d+)$/.exec(algorithm.hash.name)![1]}`; case "RSA-PSS": diff --git a/src/mechs/rsa/rsa_es.ts b/src/mechs/rsa/rsa_es.ts index a12922c..1f64cdc 100644 --- a/src/mechs/rsa/rsa_es.ts +++ b/src/mechs/rsa/rsa_es.ts @@ -1,7 +1,7 @@ import * as crypto from "crypto"; import { Convert } from "pvtsutils"; import * as core from "webcrypto-core"; -import { CryptoKey } from "../../keys"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { RsaCrypto } from "./crypto"; import { RsaPrivateKey } from "./private_key"; import { RsaPublicKey } from "./public_key"; @@ -15,7 +15,7 @@ export class RsaEsProvider extends core.ProviderCrypto { }; public async onGenerateKey(algorithm: RsaKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { - const key = await RsaCrypto.generateKey( + const keys = await RsaCrypto.generateKey( { ...algorithm, name: this.name, @@ -23,7 +23,10 @@ export class RsaEsProvider extends core.ProviderCrypto { extractable, keyUsages); - return key; + return { + privateKey: setCryptoKey(keys.privateKey as RsaPrivateKey), + publicKey: setCryptoKey(keys.publicKey as RsaPublicKey), + }; } public checkGenerateKeyParams(algorithm: RsaKeyGenParams) { @@ -62,17 +65,18 @@ export class RsaEsProvider extends core.ProviderCrypto { } public async onExportKey(format: KeyFormat, key: CryptoKey): Promise { - return RsaCrypto.exportKey(format, key); + return RsaCrypto.exportKey(format, getCryptoKey(key)); } public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: RsaHashedImportParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { const key = await RsaCrypto.importKey(format, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); - return key; + return setCryptoKey(key); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof RsaPrivateKey || key instanceof RsaPublicKey)) { + const internalKey = getCryptoKey(key); + if (!(internalKey instanceof RsaPrivateKey || internalKey instanceof RsaPublicKey)) { throw new TypeError("key: Is not RSA CryptoKey"); } } @@ -82,7 +86,7 @@ export class RsaEsProvider extends core.ProviderCrypto { private toCryptoOptions(key: RsaPrivateKey | RsaPublicKey) { const type = key.type.toUpperCase(); return { - key: `-----BEGIN ${type} KEY-----\n${key.data.toString("base64")}\n-----END ${type} KEY-----`, + key: `-----BEGIN ${type} KEY-----\n${getCryptoKey(key).data.toString("base64")}\n-----END ${type} KEY-----`, // @ts-ignore padding: crypto.constants.RSA_PKCS1_PADDING, }; diff --git a/src/mechs/rsa/rsa_oaep.ts b/src/mechs/rsa/rsa_oaep.ts index 99c58d0..bf06e8e 100644 --- a/src/mechs/rsa/rsa_oaep.ts +++ b/src/mechs/rsa/rsa_oaep.ts @@ -1,7 +1,7 @@ import crypto from "crypto"; import * as core from "webcrypto-core"; -import { CryptoKey } from "../../keys"; import { ShaCrypto } from "../sha/crypto"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { RsaCrypto } from "./crypto"; import { RsaPrivateKey } from "./private_key"; import { RsaPublicKey } from "./public_key"; @@ -16,7 +16,7 @@ import { RsaPublicKey } from "./public_key"; export class RsaOaepProvider extends core.RsaOaepProvider { public async onGenerateKey(algorithm: RsaHashedKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { - const key = await RsaCrypto.generateKey( + const keys = await RsaCrypto.generateKey( { ...algorithm, name: this.name, @@ -24,13 +24,17 @@ export class RsaOaepProvider extends core.RsaOaepProvider { extractable, keyUsages); - return key; + return { + privateKey: setCryptoKey(keys.privateKey as RsaPrivateKey), + publicKey: setCryptoKey(keys.publicKey as RsaPublicKey), + }; } public async onEncrypt(algorithm: RsaOaepParams, key: RsaPublicKey, data: ArrayBuffer): Promise { + const internalKey = getCryptoKey(key) as RsaPublicKey; const dataView = new Uint8Array(data); - const keySize = Math.ceil(key.algorithm.modulusLength >> 3); - const hashSize = ShaCrypto.size(key.algorithm.hash) >> 3; + const keySize = Math.ceil(internalKey.algorithm.modulusLength >> 3); + const hashSize = ShaCrypto.size(internalKey.algorithm.hash) >> 3; const dataLength = dataView.byteLength; const psLength = keySize - dataLength - 2 * hashSize - 2; @@ -44,7 +48,7 @@ export class RsaOaepProvider extends core.RsaOaepProvider { dataBlock.set(dataView, hashSize + psLength + 1); - const labelHash = crypto.createHash(key.algorithm.hash.name.replace("-", "")) + const labelHash = crypto.createHash(internalKey.algorithm.hash.name.replace("-", "")) .update(core.BufferSourceConverter.toUint8Array(algorithm.label || new Uint8Array(0))) .digest(); dataBlock.set(labelHash, 0); @@ -52,22 +56,22 @@ export class RsaOaepProvider extends core.RsaOaepProvider { crypto.randomFillSync(seed); - const dataBlockMask = this.mgf1(key.algorithm.hash, seed, dataBlock.length); + const dataBlockMask = this.mgf1(internalKey.algorithm.hash, seed, dataBlock.length); for (let i = 0; i < dataBlock.length; i++) { dataBlock[i] ^= dataBlockMask[i]; } - const seedMask = this.mgf1(key.algorithm.hash, dataBlock, seed.length); + const seedMask = this.mgf1(internalKey.algorithm.hash, dataBlock, seed.length); for (let i = 0; i < seed.length; i++) { seed[i] ^= seedMask[i]; } - if (!key.pem) { - key.pem = `-----BEGIN PUBLIC KEY-----\n${key.data.toString("base64")}\n-----END PUBLIC KEY-----`; + if (!internalKey.pem) { + internalKey.pem = `-----BEGIN PUBLIC KEY-----\n${internalKey.data.toString("base64")}\n-----END PUBLIC KEY-----`; } const pkcs0 = crypto.publicEncrypt({ - key: key.pem, + key: internalKey.pem, padding: crypto.constants.RSA_NO_PADDING, }, Buffer.from(message)); @@ -75,20 +79,21 @@ export class RsaOaepProvider extends core.RsaOaepProvider { } public async onDecrypt(algorithm: RsaOaepParams, key: RsaPrivateKey, data: ArrayBuffer): Promise { - const keySize = Math.ceil(key.algorithm.modulusLength >> 3); - const hashSize = ShaCrypto.size(key.algorithm.hash) >> 3; + const internalKey = getCryptoKey(key) as RsaPrivateKey; + const keySize = Math.ceil(internalKey.algorithm.modulusLength >> 3); + const hashSize = ShaCrypto.size(internalKey.algorithm.hash) >> 3; const dataLength = data.byteLength; if (dataLength !== keySize) { throw new Error("Bad data"); } - if (!key.pem) { - key.pem = `-----BEGIN PRIVATE KEY-----\n${key.data.toString("base64")}\n-----END PRIVATE KEY-----`; + if (!internalKey.pem) { + internalKey.pem = `-----BEGIN PRIVATE KEY-----\n${internalKey.data.toString("base64")}\n-----END PRIVATE KEY-----`; } let pkcs0 = crypto.privateDecrypt({ - key: key.pem, + key: internalKey.pem, padding: crypto.constants.RSA_NO_PADDING, }, Buffer.from(data)); const z = pkcs0[0]; @@ -99,17 +104,17 @@ export class RsaOaepProvider extends core.RsaOaepProvider { throw new Error("Decryption failed"); } - const seedMask = this.mgf1(key.algorithm.hash, dataBlock, seed.length); + const seedMask = this.mgf1(internalKey.algorithm.hash, dataBlock, seed.length); for (let i = 0; i < seed.length; i++) { seed[i] ^= seedMask[i]; } - const dataBlockMask = this.mgf1(key.algorithm.hash, seed, dataBlock.length); + const dataBlockMask = this.mgf1(internalKey.algorithm.hash, seed, dataBlock.length); for (let i = 0; i < dataBlock.length; i++) { dataBlock[i] ^= dataBlockMask[i]; } - const labelHash = crypto.createHash(key.algorithm.hash.name.replace("-", "")) + const labelHash = crypto.createHash(internalKey.algorithm.hash.name.replace("-", "")) .update(core.BufferSourceConverter.toUint8Array(algorithm.label || new Uint8Array(0))) .digest(); for (let i = 0; i < hashSize; i++) { @@ -138,17 +143,18 @@ export class RsaOaepProvider extends core.RsaOaepProvider { } public async onExportKey(format: KeyFormat, key: CryptoKey): Promise { - return RsaCrypto.exportKey(format, key); + return RsaCrypto.exportKey(format, getCryptoKey(key)); } public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: RsaHashedImportParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { const key = await RsaCrypto.importKey(format, keyData, { ...algorithm, name: this.name }, extractable, keyUsages); - return key; + return setCryptoKey(key); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof RsaPrivateKey || key instanceof RsaPublicKey)) { + const internalKey = getCryptoKey(key); + if (!(internalKey instanceof RsaPrivateKey || internalKey instanceof RsaPublicKey)) { throw new TypeError("key: Is not RSA CryptoKey"); } } @@ -159,7 +165,7 @@ export class RsaOaepProvider extends core.RsaOaepProvider { * @param seed * @param length */ - protected mgf1(algorithm: Algorithm, seed: Uint8Array, length: number = 0) { + protected mgf1(algorithm: Algorithm, seed: Uint8Array, length = 0) { const hashSize = ShaCrypto.size(algorithm) >> 3; const mask = new Uint8Array(length); const counter = new Uint8Array(4); diff --git a/src/mechs/rsa/rsa_pss.ts b/src/mechs/rsa/rsa_pss.ts index 489393b..059fceb 100644 --- a/src/mechs/rsa/rsa_pss.ts +++ b/src/mechs/rsa/rsa_pss.ts @@ -1,5 +1,5 @@ import * as core from "webcrypto-core"; -import { CryptoKey } from "../../keys"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { RsaCrypto } from "./crypto"; import { RsaPrivateKey } from "./private_key"; import { RsaPublicKey } from "./public_key"; @@ -7,7 +7,7 @@ import { RsaPublicKey } from "./public_key"; export class RsaPssProvider extends core.RsaPssProvider { public async onGenerateKey(algorithm: RsaHashedKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { - const key = await RsaCrypto.generateKey( + const keys = await RsaCrypto.generateKey( { ...algorithm, name: this.name, @@ -15,29 +15,33 @@ export class RsaPssProvider extends core.RsaPssProvider { extractable, keyUsages); - return key; + return { + privateKey: setCryptoKey(keys.privateKey as RsaPrivateKey), + publicKey: setCryptoKey(keys.publicKey as RsaPublicKey), + }; } public async onSign(algorithm: RsaPssParams, key: RsaPrivateKey, data: ArrayBuffer): Promise { - return RsaCrypto.sign(algorithm, key, new Uint8Array(data)); + return RsaCrypto.sign(algorithm, getCryptoKey(key) as RsaPrivateKey, new Uint8Array(data)); } public async onVerify(algorithm: RsaPssParams, key: RsaPublicKey, signature: ArrayBuffer, data: ArrayBuffer): Promise { - return RsaCrypto.verify(algorithm, key, new Uint8Array(signature), new Uint8Array(data)); + return RsaCrypto.verify(algorithm, getCryptoKey(key) as RsaPublicKey, new Uint8Array(signature), new Uint8Array(data)); } public async onExportKey(format: KeyFormat, key: CryptoKey): Promise { - return RsaCrypto.exportKey(format, key); + return RsaCrypto.exportKey(format, getCryptoKey(key)); } public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: RsaHashedImportParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { const key = await RsaCrypto.importKey(format, keyData, {...algorithm, name: this.name}, extractable, keyUsages); - return key; + return setCryptoKey(key); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof RsaPrivateKey || key instanceof RsaPublicKey)) { + const internalKey = getCryptoKey(key); + if (!(internalKey instanceof RsaPrivateKey || internalKey instanceof RsaPublicKey)) { throw new TypeError("key: Is not RSA CryptoKey"); } } diff --git a/src/mechs/rsa/rsa_ssa.ts b/src/mechs/rsa/rsa_ssa.ts index 046ecb4..7eca5f3 100644 --- a/src/mechs/rsa/rsa_ssa.ts +++ b/src/mechs/rsa/rsa_ssa.ts @@ -1,5 +1,5 @@ import * as core from "webcrypto-core"; -import { CryptoKey } from "../../keys"; +import { setCryptoKey, getCryptoKey } from "../storage"; import { RsaCrypto } from "./crypto"; import { RsaPrivateKey } from "./private_key"; import { RsaPublicKey } from "./public_key"; @@ -7,7 +7,7 @@ import { RsaPublicKey } from "./public_key"; export class RsaSsaProvider extends core.RsaSsaProvider { public async onGenerateKey(algorithm: RsaHashedKeyGenParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { - const key = await RsaCrypto.generateKey( + const keys = await RsaCrypto.generateKey( { ...algorithm, name: this.name, @@ -15,29 +15,33 @@ export class RsaSsaProvider extends core.RsaSsaProvider { extractable, keyUsages); - return key; + return { + privateKey: setCryptoKey(keys.privateKey as RsaPrivateKey), + publicKey: setCryptoKey(keys.publicKey as RsaPublicKey), + }; } public async onSign(algorithm: Algorithm, key: RsaPrivateKey, data: ArrayBuffer): Promise { - return RsaCrypto.sign(algorithm, key, new Uint8Array(data)); + return RsaCrypto.sign(algorithm, getCryptoKey(key) as RsaPrivateKey, new Uint8Array(data)); } public async onVerify(algorithm: Algorithm, key: RsaPublicKey, signature: ArrayBuffer, data: ArrayBuffer): Promise { - return RsaCrypto.verify(algorithm, key, new Uint8Array(signature), new Uint8Array(data)); + return RsaCrypto.verify(algorithm, getCryptoKey(key) as RsaPublicKey, new Uint8Array(signature), new Uint8Array(data)); } public async onExportKey(format: KeyFormat, key: CryptoKey): Promise { - return RsaCrypto.exportKey(format, key); + return RsaCrypto.exportKey(format, getCryptoKey(key)); } public async onImportKey(format: KeyFormat, keyData: JsonWebKey | ArrayBuffer, algorithm: RsaHashedImportParams, extractable: boolean, keyUsages: KeyUsage[]): Promise { const key = await RsaCrypto.importKey(format, keyData, {...algorithm, name: this.name}, extractable, keyUsages); - return key; + return setCryptoKey(key); } public checkCryptoKey(key: CryptoKey, keyUsage?: KeyUsage) { super.checkCryptoKey(key, keyUsage); - if (!(key instanceof RsaPrivateKey || key instanceof RsaPublicKey)) { + const internalKey = getCryptoKey(key); + if (!(internalKey instanceof RsaPrivateKey || internalKey instanceof RsaPublicKey)) { throw new TypeError("key: Is not RSA CryptoKey"); } } diff --git a/src/mechs/storage.ts b/src/mechs/storage.ts new file mode 100644 index 0000000..3d3e2e9 --- /dev/null +++ b/src/mechs/storage.ts @@ -0,0 +1,21 @@ +import * as core from "webcrypto-core"; +import { CryptoKey as InternalCryptoKey } from "../keys"; + +const keyStorage = new WeakMap(); + +export function getCryptoKey(key: core.CryptoKey) { + const res = keyStorage.get(key); + if (!res) { + throw new core.OperationError("Cannot get CryptoKey from secure storage"); + } + return res; +} + +export function setCryptoKey(value: InternalCryptoKey) { + const key = core.CryptoKey.create(value.algorithm, value.type, value.extractable, value.usages); + Object.freeze(key); + + keyStorage.set(key, value); + + return key; +} diff --git a/test/asn.ts b/test/asn.ts index 4a7944e..76d1a95 100644 --- a/test/asn.ts +++ b/test/asn.ts @@ -1,6 +1,6 @@ +import assert from "assert"; import { AsnParser, AsnSerializer } from "@peculiar/asn1-schema"; import { JsonParser, JsonSerializer } from "@peculiar/json-schema"; -import assert from "assert"; import * as asn from "../src/asn"; context("ASN", () => { diff --git a/test/des.ts b/test/des.ts index 014ad49..e9fc87b 100644 --- a/test/des.ts +++ b/test/des.ts @@ -1,4 +1,3 @@ -import assert from "assert"; import * as core from "webcrypto-core"; import { Crypto } from "../src"; import { DesCbcParams } from "../src/mechs"; diff --git a/test/helper.ts b/test/helper.ts index 8f04ae3..7d4f995 100644 --- a/test/helper.ts +++ b/test/helper.ts @@ -150,9 +150,10 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { params.forEach((param) => { context(param.name, () => { //#region Generate key - if (param.actions.generateKey) { + const generateKey = param.actions.generateKey; + if (generateKey) { context("Generate Key", () => { - param.actions.generateKey!.forEach((action, index) => { + generateKey.forEach((action, index) => { wrapTest(async () => { const algorithm = Object.assign({}, action.algorithm); algorithm.name = algorithm.name.toLowerCase(); @@ -184,9 +185,10 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { //#endregion //#region encrypt - if (param.actions.encrypt) { + const encrypt = param.actions.encrypt; + if (encrypt) { context("Encrypt/Decrypt", () => { - param.actions.encrypt!.forEach((action, index) => { + encrypt.forEach((action, index) => { wrapTest(async () => { // import keys const keys = await getKeys(crypto, action.key); @@ -212,9 +214,10 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { //#endregion //#region Import/Export - if (param.actions.import) { + const importFn = param.actions.import; + if (importFn) { context("Import/Export", () => { - param.actions.import!.forEach((action, index) => { + importFn.forEach((action, index) => { wrapTest(async () => { const importedKey = await crypto.subtle.importKey( action.format, @@ -223,7 +226,7 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { action.extractable, action.keyUsages); - // Can't continue if key is not exctractable. + // Can't continue if key is not extractable. if (!action.extractable) { return; } @@ -244,9 +247,10 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { //#endregion //#region Sign/Verify - if (param.actions.sign) { + const sign = param.actions.sign; + if (sign) { context("Sign/Verify", () => { - param.actions.sign!.forEach((action, index) => { + sign.forEach((action, index) => { wrapTest(async () => { // import keys const keys = await getKeys(crypto, action.key); @@ -275,9 +279,10 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { //#endregion //#region Derive bits - if (param.actions.deriveBits) { + const deriveBits = param.actions.deriveBits; + if (deriveBits) { context("Derive bits", () => { - param.actions.deriveBits!.forEach((action, index) => { + deriveBits.forEach((action, index) => { wrapTest(async () => { // import keys const keys = await getKeys(crypto, action.key); @@ -295,9 +300,10 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { //#endregion //#region Derive key - if (param.actions.deriveKey) { + const deriveKey = param.actions.deriveKey; + if (deriveKey) { context("Derive key", () => { - param.actions.deriveKey!.forEach((action, index) => { + deriveKey.forEach((action, index) => { wrapTest(async () => { // import keys const keys = await getKeys(crypto, action.key); @@ -320,9 +326,10 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { //#endregion //#region Digest - if (param.actions.digest) { + const digest = param.actions.digest; + if (digest) { context("Digest", () => { - param.actions.digest!.forEach((action, index) => { + digest.forEach((action, index) => { wrapTest(async () => { const hash = await crypto.subtle.digest(action.algorithm, action.data); assert.equal(Convert.ToHex(hash), Convert.ToHex(action.hash)); @@ -333,9 +340,10 @@ export function testCrypto(crypto: Crypto, params: ITestParams[]) { //#endregion //#region Wrap/Unwrap key - if (param.actions.wrapKey) { + const wrapKey = param.actions.wrapKey; + if (wrapKey) { context("Wrap/Unwrap key", () => { - param.actions.wrapKey!.forEach((action, index) => { + wrapKey.forEach((action, index) => { wrapTest(async () => { const wKey = (await getKeys(crypto, action.wKey)).privateKey; const key = await getKeys(crypto, action.key); diff --git a/test/hkdf.ts b/test/hkdf.ts index eebe469..a481674 100644 --- a/test/hkdf.ts +++ b/test/hkdf.ts @@ -1,4 +1,3 @@ -import { Convert } from "pvtsutils"; import { Crypto } from "../src"; import { testCrypto } from "./helper"; diff --git a/test/mocha.opts b/test/mocha.opts deleted file mode 100644 index 5ed99a2..0000000 --- a/test/mocha.opts +++ /dev/null @@ -1,2 +0,0 @@ ---require ts-node/register -test/**/*.ts \ No newline at end of file diff --git a/test/sha.ts b/test/sha.ts index bfe66e6..fad61bf 100644 --- a/test/sha.ts +++ b/test/sha.ts @@ -1,6 +1,6 @@ import { Convert } from "pvtsutils"; import { Crypto } from "../src"; -import { ITestGenerateKeyAction, testCrypto } from "./helper"; +import { testCrypto } from "./helper"; context("SHA", () => { diff --git a/tslint.json b/tslint.json deleted file mode 100644 index 4af46f6..0000000 --- a/tslint.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "defaultSeverity": "error", - "extends": [ - "tslint:recommended" - ], - "jsRules": {}, - "rules": { - "max-line-length": false, - "no-bitwise": false, - "object-literal-sort-keys": false, - "no-namespace": false, - "max-classes-per-file": false - }, - "rulesDirectory": [] -} \ No newline at end of file