From cfe87ba63fda281469901cbdba47d4795282e14e Mon Sep 17 00:00:00 2001 From: chunningham <12844144+chunningham@users.noreply.github.com> Date: Tue, 21 Jan 2025 17:01:21 +0100 Subject: [PATCH] ABNF parser rewrite (#213) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * A complete re-write of the ABNF parser. Removed dependencies on uri-js and valid-url. Added many new unit tests for validating both the message URI and the resource URIs. Added a script to re-generate the ABNF grammar object whenever the ABNF grammar needs to be changed. * Updated package/siwe-parser. package.json: 1)the dependency on apg-js is the newly published version 4.4.0, 2)the script "apg" will generate a typescript grammar object from the ABNF grammar siwe-abnf.txt. Added an optional "doTrace" parameter to the constructor of ParsedMessage. The default is "false". If set to "true" apg-js will trace the parse tree of parsed message and write it to output/siwe-parser-trace.html. Consequently the output directory has been added to ".gitignore" and ".npmignore". * Committed four files missed in the last commit. * Modified the ABNF grammar and parser to match the spec for (present/empty/missing) statement/resources. * Added new function "isUri()" to "packages/siwe-parser/lib/abnf.ts". Added "packages/siwe-parser/lib/t-isUri.test.ts" for unit testing of the "isUri" function. Added tests in the object block of the “SiweMessage” constructor for testing the EIP-55 address, the URI and the resources URIs. Added “packages/siwe/lib/objects.test.ts” for unit testing of the object block. * Modifed the ParsedMessage callbacks to validate the semantics as well as the syntax of date times. Removed the SiweMessage private function validateMessage(). Replaced it in the message object block of the constructor by parsing the stringified message object. In this way both the message and the message object get exactly the same validation. Fixed a bug for the case of an empty statement in the function toMessage(). * Updated validation of date-times in ParsedMessage. Fixed message object validation in SiweMessage. * Removed debugging (doTrace) code from t-chars.test.ts". * Fixed siwe/lib/utils.ts bug. Converted all unit tests to JSON file methodology. * Removed a development-only script from siwe package.json. * remove commented code * fix invalid opts check * fix tests, SiweErrorType has no values, is not object * Fix test * Fix typos * Lint files * Typos * Upgrade to ES2018 * Remove deprecated method * Bump version * Bump siwe-parser version --------- Co-authored-by: Lowell D. Thomas Co-authored-by: Gregorio --- package-lock.json | 1104 ++++++++++------------ packages/siwe-parser/lib/abnf.ts | 507 +++------- packages/siwe-parser/lib/callbacks.ts | 529 +++++++++++ packages/siwe-parser/lib/parsers.test.ts | 51 +- packages/siwe-parser/lib/parsers.ts | 10 +- packages/siwe-parser/lib/siwe-abnf.txt | 212 +++++ packages/siwe-parser/lib/siwe-grammar.ts | 1042 ++++++++++++++++++++ packages/siwe-parser/lib/unit.test.ts | 116 +++ packages/siwe-parser/lib/utils.ts | 42 +- packages/siwe-parser/package.json | 9 +- packages/siwe-parser/tsconfig.json | 6 +- packages/siwe/lib/client.test.ts | 42 +- packages/siwe/lib/client.ts | 132 +-- packages/siwe/lib/ethersCompat.ts | 42 +- packages/siwe/lib/objects.test.ts | 21 + packages/siwe/lib/types.ts | 15 +- packages/siwe/lib/utils.ts | 4 +- packages/siwe/package.json | 8 +- packages/siwe/tsconfig.json | 2 +- test/invalid_chars.json | 202 ++++ test/invalid_resources.json | 18 + test/invalid_uris.json | 18 + test/message_objects.json | 54 ++ test/valid_chars.json | 42 + test/valid_resources.json | 34 + test/valid_specification.json | 74 ++ test/valid_uris.json | 308 ++++++ 27 files changed, 3434 insertions(+), 1210 deletions(-) create mode 100644 packages/siwe-parser/lib/callbacks.ts create mode 100644 packages/siwe-parser/lib/siwe-abnf.txt create mode 100644 packages/siwe-parser/lib/siwe-grammar.ts create mode 100644 packages/siwe-parser/lib/unit.test.ts create mode 100644 packages/siwe/lib/objects.test.ts create mode 100644 test/invalid_chars.json create mode 100644 test/invalid_resources.json create mode 100644 test/invalid_uris.json create mode 100644 test/message_objects.json create mode 100644 test/valid_chars.json create mode 100644 test/valid_resources.json create mode 100644 test/valid_specification.json create mode 100644 test/valid_uris.json diff --git a/package-lock.json b/package-lock.json index b7c91fa0..4dd91ac7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2260,9 +2260,9 @@ } }, "node_modules/@lerna/legacy-package-management/node_modules/make-fetch-happen/node_modules/ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "dependencies": { "minipass": "^7.0.3" @@ -2272,9 +2272,9 @@ } }, "node_modules/@lerna/legacy-package-management/node_modules/make-fetch-happen/node_modules/ssri/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -2302,9 +2302,9 @@ } }, "node_modules/@lerna/legacy-package-management/node_modules/minipass-fetch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", - "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, "dependencies": { "minipass": "^7.0.3", @@ -2319,9 +2319,9 @@ } }, "node_modules/@lerna/legacy-package-management/node_modules/minipass-fetch/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -2633,9 +2633,9 @@ } }, "node_modules/@npmcli/arborist/node_modules/gauge": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-5.0.1.tgz", - "integrity": "sha512-CmykPMJGuNan/3S4kZOpvvPYSNqSHANiWnh9XcMU2pSjtBfF0XzZ2p1bFAxTbnFxyBuPxQYHhzwaoOmUdqzvxQ==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-5.0.2.tgz", + "integrity": "sha512-pMaFftXPtiGIHCJHdcUUx9Rby/rFT/Kkt3fIIGCs+9PMDIljSyRiqraTlxNtBReJRDfUefpa263RQ3vnp5G/LQ==", "dev": true, "dependencies": { "aproba": "^1.0.3 || ^2.0.0", @@ -2651,6 +2651,15 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/@npmcli/arborist/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@npmcli/arborist/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -2736,9 +2745,9 @@ } }, "node_modules/@npmcli/arborist/node_modules/ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "dependencies": { "minipass": "^7.0.3" @@ -2902,25 +2911,25 @@ "dev": true }, "node_modules/@npmcli/installed-package-contents": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz", - "integrity": "sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz", + "integrity": "sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==", "dev": true, "dependencies": { "npm-bundled": "^3.0.0", "npm-normalize-package-bin": "^3.0.0" }, "bin": { - "installed-package-contents": "lib/index.js" + "installed-package-contents": "bin/index.js" }, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/@npmcli/map-workspaces": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-3.0.4.tgz", - "integrity": "sha512-Z0TbvXkRbacjFFLpVpV0e2mheCh+WzQpcqL+4xp49uNJOxOnIAPZyXtUxZ5Qn3QBTGKA11Exjd9a5411rBrhDg==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-3.0.6.tgz", + "integrity": "sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA==", "dev": true, "dependencies": { "@npmcli/name-from-folder": "^2.0.0", @@ -2993,6 +3002,15 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/@npmcli/metavuln-calculator/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@npmcli/metavuln-calculator/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -3040,21 +3058,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/@npmcli/move-file/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/@npmcli/name-from-folder": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-2.0.0.tgz", @@ -3121,6 +3124,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@npmcli/package-json/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@npmcli/package-json/node_modules/minimatch": { "version": "9.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", @@ -3212,12 +3224,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/@npmcli/run-script/node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, "node_modules/@npmcli/run-script/node_modules/npm-normalize-package-bin": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", @@ -3751,9 +3757,9 @@ } }, "node_modules/@sigstore/sign/node_modules/minipass-fetch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", - "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, "dependencies": { "minipass": "^7.0.3", @@ -3768,18 +3774,18 @@ } }, "node_modules/@sigstore/sign/node_modules/minipass-fetch/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/@sigstore/sign/node_modules/ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "dependencies": { "minipass": "^7.0.3" @@ -3789,9 +3795,9 @@ } }, "node_modules/@sigstore/sign/node_modules/ssri/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -4559,9 +4565,9 @@ } }, "node_modules/apg-js": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/apg-js/-/apg-js-4.3.0.tgz", - "integrity": "sha512-8U8MULS+JocCnm11bfrVS4zxtAcE3uOiCAI21SnjDrV9LNhMSGwTGGeko3QfyK1JLWwT7KebFqJMB2puzfdFMQ==" + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/apg-js/-/apg-js-4.4.0.tgz", + "integrity": "sha512-fefmXFknJmtgtNEXfPwZKYkMFX4Fyeyz+fNF6JWp87biGOPslJbCBVU158zvKRZfHBKnJDy8CMM40oLFGkXT8Q==" }, "node_modules/aproba": { "version": "2.0.0", @@ -4802,9 +4808,9 @@ "dev": true }, "node_modules/bin-links": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.3.tgz", - "integrity": "sha512-obsRaULtJurnfox/MDwgq6Yo9kzbv1CPTk/1/s7Z/61Lezc8IKkFCOXNeVLXz0456WRzBQmSsDWlai2tIhBsfA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.4.tgz", + "integrity": "sha512-cMtq4W5ZsEwcutJrVId+a/tjt8GSbS+h0oNkdl6+6rBuEv8Ot33Bevj5KPm40t309zuhVic8NjpuL42QCiJWWA==", "dev": true, "dependencies": { "cmd-shim": "^6.0.0", @@ -4817,9 +4823,9 @@ } }, "node_modules/bin-links/node_modules/cmd-shim": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.2.tgz", - "integrity": "sha512-+FFYbB0YLaAkhkcrjkyNLYDiOsFSfRjwjY19LXk/psmMx1z00xlCv7hhQoTGXXIKi+YXHL/iiFo8NqMVQX9nOw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.3.tgz", + "integrity": "sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA==", "dev": true, "engines": { "node": "^14.17.0 || ^16.13.0 || >=18.0.0" @@ -5117,9 +5123,9 @@ } }, "node_modules/cacache/node_modules/ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "dependencies": { "minipass": "^7.0.3" @@ -5904,21 +5910,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/del/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -6141,9 +6132,9 @@ } }, "node_modules/envinfo": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.12.0.tgz", - "integrity": "sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", "dev": true, "bin": { "envinfo": "dist/cli.js" @@ -6919,21 +6910,6 @@ "node": "^10.12.0 || >=12.0.0" } }, - "node_modules/flat-cache/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/flatted": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", @@ -8214,9 +8190,9 @@ } }, "node_modules/jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", + "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", "dev": true, "dependencies": { "async": "^3.2.3", @@ -8875,13 +8851,10 @@ "dev": true }, "node_modules/json-parse-even-better-errors": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", - "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==", - "dev": true, - "engines": { - "node": "^14.17.0 || ^16.13.0 || >=18.0.0" - } + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", + "dev": true }, "node_modules/json-schema-traverse": { "version": "0.4.1", @@ -9157,6 +9130,48 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/lerna/node_modules/glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/lerna/node_modules/glob/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/lerna/node_modules/glob/node_modules/minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/lerna/node_modules/graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -9232,6 +9247,33 @@ "node": "*" } }, + "node_modules/lerna/node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/lerna/node_modules/rimraf": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", + "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", + "dev": true, + "dependencies": { + "glob": "^9.2.0" + }, + "bin": { + "rimraf": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/lerna/node_modules/semver": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", @@ -9491,9 +9533,9 @@ } }, "node_modules/libnpmpublish/node_modules/ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "dependencies": { "minipass": "^7.0.3" @@ -9816,63 +9858,6 @@ "node": ">=8" } }, - "node_modules/make-fetch-happen/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/make-fetch-happen/node_modules/rimraf/node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/make-fetch-happen/node_modules/rimraf/node_modules/glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/make-fetch-happen/node_modules/rimraf/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, "node_modules/make-fetch-happen/node_modules/semver": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", @@ -10252,9 +10237,9 @@ } }, "node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -10637,9 +10622,9 @@ } }, "node_modules/node-gyp-build": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", - "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", "dev": true, "bin": { "node-gyp-build": "bin.js", @@ -10680,21 +10665,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/node-gyp/node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, "node_modules/node-gyp/node_modules/semver": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", @@ -10729,9 +10699,9 @@ "dev": true }, "node_modules/nopt": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz", - "integrity": "sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", "dev": true, "dependencies": { "abbrev": "^2.0.0" @@ -11151,9 +11121,9 @@ } }, "node_modules/npm-registry-fetch/node_modules/minipass-fetch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", - "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, "dependencies": { "minipass": "^7.0.3", @@ -11168,9 +11138,9 @@ } }, "node_modules/npm-registry-fetch/node_modules/minipass-fetch/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -11219,9 +11189,9 @@ } }, "node_modules/npm-registry-fetch/node_modules/ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "dependencies": { "minipass": "^7.0.3" @@ -11231,9 +11201,9 @@ } }, "node_modules/npm-registry-fetch/node_modules/ssri/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -11791,18 +11761,18 @@ } }, "node_modules/pacote/node_modules/glob/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/pacote/node_modules/ignore-walk": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.4.tgz", - "integrity": "sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.5.tgz", + "integrity": "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==", "dev": true, "dependencies": { "minimatch": "^9.0.0" @@ -11811,6 +11781,15 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/pacote/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/pacote/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -11905,9 +11884,9 @@ } }, "node_modules/pacote/node_modules/ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "dependencies": { "minipass": "^7.0.3" @@ -11917,9 +11896,9 @@ } }, "node_modules/pacote/node_modules/ssri/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -11984,6 +11963,15 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/parse-conflict-json/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/parse-json": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", @@ -12002,12 +11990,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse-json/node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, "node_modules/parse-json/node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -12082,9 +12064,9 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", "dev": true, "engines": { "node": "14 || >=16.14" @@ -12309,6 +12291,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "engines": { "node": ">=6" } @@ -12423,6 +12406,15 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/read-package-json-fast/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/read-package-json/node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -12463,12 +12455,6 @@ "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "node_modules/read-package-json/node_modules/json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, "node_modules/read-package-json/node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", @@ -12821,92 +12807,38 @@ }, "node_modules/retry": { "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rimraf": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", - "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", - "dev": true, - "dependencies": { - "glob": "^9.2.0" - }, - "bin": { - "rimraf": "dist/cjs/src/bin.js" - }, - "engines": { - "node": ">=14" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/rimraf/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==", "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" + "engines": { + "node": ">= 4" } }, - "node_modules/rimraf/node_modules/glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - }, "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "node_modules/rimraf/node_modules/minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "dependencies": { - "brace-expansion": "^2.0.1" + "glob": "^7.1.3" }, - "engines": { - "node": ">=16 || 14 >=14.17" + "bin": { + "rimraf": "bin.js" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/rimraf/node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", @@ -13110,9 +13042,9 @@ } }, "node_modules/sigstore/node_modules/minipass-fetch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", - "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, "dependencies": { "minipass": "^7.0.3", @@ -13127,18 +13059,18 @@ } }, "node_modules/sigstore/node_modules/minipass-fetch/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/sigstore/node_modules/ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "dependencies": { "minipass": "^7.0.3" @@ -13148,9 +13080,9 @@ } }, "node_modules/sigstore/node_modules/ssri/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -13922,9 +13854,9 @@ } }, "node_modules/tuf-js/node_modules/minipass-fetch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", - "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, "dependencies": { "minipass": "^7.0.3", @@ -13939,18 +13871,18 @@ } }, "node_modules/tuf-js/node_modules/minipass-fetch/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" } }, "node_modules/tuf-js/node_modules/ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "dependencies": { "minipass": "^7.0.3" @@ -13960,9 +13892,9 @@ } }, "node_modules/tuf-js/node_modules/ssri/node_modules/minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -14182,6 +14114,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "dependencies": { "punycode": "^2.1.0" } @@ -14221,11 +14154,6 @@ "node": ">=10.12.0" } }, - "node_modules/valid-url": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", - "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" - }, "node_modules/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", @@ -14601,9 +14529,7 @@ "license": "Apache-2.0", "dependencies": { "@spruceid/siwe-parser": "^2.1.2", - "@stablelib/random": "^1.0.1", - "uri-js": "^4.4.1", - "valid-url": "^1.0.9" + "@stablelib/random": "^1.0.1" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^5.23.0", @@ -14622,9 +14548,7 @@ "license": "Apache-2.0", "dependencies": { "@noble/hashes": "^1.1.2", - "apg-js": "^4.3.0", - "uri-js": "^4.4.1", - "valid-url": "^1.0.9" + "apg-js": "^4.4.0" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^5.23.0", @@ -16210,18 +16134,18 @@ "dev": true }, "ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "requires": { "minipass": "^7.0.3" }, "dependencies": { "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true } } @@ -16244,9 +16168,9 @@ "dev": true }, "minipass-fetch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", - "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, "requires": { "encoding": "^0.1.13", @@ -16256,9 +16180,9 @@ }, "dependencies": { "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true } } @@ -16502,9 +16426,9 @@ } }, "gauge": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-5.0.1.tgz", - "integrity": "sha512-CmykPMJGuNan/3S4kZOpvvPYSNqSHANiWnh9XcMU2pSjtBfF0XzZ2p1bFAxTbnFxyBuPxQYHhzwaoOmUdqzvxQ==", + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-5.0.2.tgz", + "integrity": "sha512-pMaFftXPtiGIHCJHdcUUx9Rby/rFT/Kkt3fIIGCs+9PMDIljSyRiqraTlxNtBReJRDfUefpa263RQ3vnp5G/LQ==", "dev": true, "requires": { "aproba": "^1.0.3 || ^2.0.0", @@ -16517,6 +16441,12 @@ "wide-align": "^1.1.5" } }, + "json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -16575,9 +16505,9 @@ "dev": true }, "ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "requires": { "minipass": "^7.0.3" @@ -16704,9 +16634,9 @@ } }, "@npmcli/installed-package-contents": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.0.2.tgz", - "integrity": "sha512-xACzLPhnfD51GKvTOOuNX2/V4G4mz9/1I2MfDoye9kBM3RYe5g2YbscsaGoTlaWqkxeiapBWyseULVKpSVHtKQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@npmcli/installed-package-contents/-/installed-package-contents-2.1.0.tgz", + "integrity": "sha512-c8UuGLeZpm69BryRykLuKRyKFZYJsZSCT4aVY5ds4omyZqJ172ApzgfKJ5eV/r3HgLdUYgFVe54KSFVjKoe27w==", "dev": true, "requires": { "npm-bundled": "^3.0.0", @@ -16714,9 +16644,9 @@ } }, "@npmcli/map-workspaces": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-3.0.4.tgz", - "integrity": "sha512-Z0TbvXkRbacjFFLpVpV0e2mheCh+WzQpcqL+4xp49uNJOxOnIAPZyXtUxZ5Qn3QBTGKA11Exjd9a5411rBrhDg==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-3.0.6.tgz", + "integrity": "sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA==", "dev": true, "requires": { "@npmcli/name-from-folder": "^2.0.0", @@ -16770,6 +16700,12 @@ "semver": "^7.3.5" }, "dependencies": { + "json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -16804,17 +16740,6 @@ "requires": { "mkdirp": "^1.0.4", "rimraf": "^3.0.2" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } } }, "@npmcli/name-from-folder": { @@ -16865,6 +16790,12 @@ "path-scurry": "^1.10.2" } }, + "json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true + }, "minimatch": { "version": "9.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.4.tgz", @@ -16933,12 +16864,6 @@ "infer-owner": "^1.0.4" } }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, "npm-normalize-package-bin": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz", @@ -17317,9 +17242,9 @@ "dev": true }, "minipass-fetch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", - "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, "requires": { "encoding": "^0.1.13", @@ -17329,26 +17254,26 @@ }, "dependencies": { "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true } } }, "ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "requires": { "minipass": "^7.0.3" }, "dependencies": { "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true } } @@ -17395,12 +17320,10 @@ "@noble/hashes": "^1.1.2", "@typescript-eslint/eslint-plugin": "^5.23.0", "@typescript-eslint/parser": "^5.23.0", - "apg-js": "^4.3.0", + "apg-js": "^4.4.0", "eslint": "^8.15.0", "eslint-config-prettier": "^8.5.0", - "prettier": "^2.6.2", - "uri-js": "^4.4.1", - "valid-url": "^1.0.9" + "prettier": "^2.6.2" } }, "@stablelib/binary": { @@ -17952,9 +17875,9 @@ } }, "apg-js": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/apg-js/-/apg-js-4.3.0.tgz", - "integrity": "sha512-8U8MULS+JocCnm11bfrVS4zxtAcE3uOiCAI21SnjDrV9LNhMSGwTGGeko3QfyK1JLWwT7KebFqJMB2puzfdFMQ==" + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/apg-js/-/apg-js-4.4.0.tgz", + "integrity": "sha512-fefmXFknJmtgtNEXfPwZKYkMFX4Fyeyz+fNF6JWp87biGOPslJbCBVU158zvKRZfHBKnJDy8CMM40oLFGkXT8Q==" }, "aproba": { "version": "2.0.0", @@ -18144,9 +18067,9 @@ "dev": true }, "bin-links": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.3.tgz", - "integrity": "sha512-obsRaULtJurnfox/MDwgq6Yo9kzbv1CPTk/1/s7Z/61Lezc8IKkFCOXNeVLXz0456WRzBQmSsDWlai2tIhBsfA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-4.0.4.tgz", + "integrity": "sha512-cMtq4W5ZsEwcutJrVId+a/tjt8GSbS+h0oNkdl6+6rBuEv8Ot33Bevj5KPm40t309zuhVic8NjpuL42QCiJWWA==", "dev": true, "requires": { "cmd-shim": "^6.0.0", @@ -18156,9 +18079,9 @@ }, "dependencies": { "cmd-shim": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.2.tgz", - "integrity": "sha512-+FFYbB0YLaAkhkcrjkyNLYDiOsFSfRjwjY19LXk/psmMx1z00xlCv7hhQoTGXXIKi+YXHL/iiFo8NqMVQX9nOw==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-6.0.3.tgz", + "integrity": "sha512-FMabTRlc5t5zjdenF6mS0MBeFZm0XqHqeOkcskKFb/LYCcRQ5fVgLOHVc4Lq9CqABd9zhjwPjMBCJvMCziSVtA==", "dev": true }, "read-cmd-shim": { @@ -18372,9 +18295,9 @@ } }, "ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "requires": { "minipass": "^7.0.3" @@ -18950,17 +18873,6 @@ "p-map": "^4.0.0", "rimraf": "^3.0.2", "slash": "^3.0.0" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } } }, "delayed-stream": { @@ -19141,9 +19053,9 @@ "dev": true }, "envinfo": { - "version": "7.12.0", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.12.0.tgz", - "integrity": "sha512-Iw9rQJBGpJRd3rwXm9ft/JiGoAZmLxxJZELYDQoPRZ4USVhkKtIcNBPw6U+/K2mBpaqM25JSV6Yl4Az9vO2wJg==", + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.13.0.tgz", + "integrity": "sha512-cvcaMr7KqXVh4nyzGTVqTum+gAiL265x5jUWQIDLq//zOGbW+gSW/C+OWLleY/rs9Qole6AZLMXPbtIFQbqu+Q==", "dev": true }, "err-code": { @@ -19700,17 +19612,6 @@ "flatted": "^3.2.9", "keyv": "^4.5.3", "rimraf": "^3.0.2" - }, - "dependencies": { - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } } }, "flatted": { @@ -20682,9 +20583,9 @@ } }, "jake": { - "version": "10.8.7", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.7.tgz", - "integrity": "sha512-ZDi3aP+fG/LchyBzUM804VjddnwfSfsdeYkwt8NcbKRvo4rFkjhs456iLFn3k2ZUWvNe4i48WACDbza8fhq2+w==", + "version": "10.9.1", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.1.tgz", + "integrity": "sha512-61btcOHNnLnsOdtLgA5efqQWjnSi/vow5HbI7HMdKKWqvrKR1bLK3BPlJn9gcSaP2ewuamUSMB5XEy76KUIS2w==", "dev": true, "requires": { "async": "^3.2.3", @@ -21192,9 +21093,9 @@ "dev": true }, "json-parse-even-better-errors": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.1.tgz", - "integrity": "sha512-aatBvbL26wVUCLmbWdCpeu9iF5wOyWpagiKkInA+kfws3sWdBrTnsvN2CKcyCYyUrc7rebNBlK6+kteg7ksecg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", "dev": true }, "json-schema-traverse": { @@ -21421,6 +21322,38 @@ "integrity": "sha512-A1B3Bh1UmL0bidM/YX2NsCOTnGJePL9rO/M+Mw3m9f2gUpfokS0hi5Eah0WSUEWZdZhIZtMjkIYS7mDfOqNHbg==", "dev": true }, + "glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } + }, "graceful-fs": { "version": "4.2.10", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", @@ -21477,6 +21410,21 @@ "brace-expansion": "^1.1.7" } }, + "minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true + }, + "rimraf": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", + "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", + "dev": true, + "requires": { + "glob": "^9.2.0" + } + }, "semver": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", @@ -21679,9 +21627,9 @@ } }, "ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "requires": { "minipass": "^7.0.3" @@ -21944,50 +21892,6 @@ "yallist": "^4.0.0" } }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - }, - "dependencies": { - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "requires": { - "brace-expansion": "^1.1.7" - } - } - } - }, "semver": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", @@ -22278,9 +22182,9 @@ } }, "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true }, "minipass-collect": { @@ -22615,15 +22519,6 @@ "abbrev": "^1.0.0" } }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, "semver": { "version": "7.6.0", "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.0.tgz", @@ -22642,9 +22537,9 @@ } }, "node-gyp-build": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.0.tgz", - "integrity": "sha512-u6fs2AEUljNho3EYTJNBfImO5QTo/J/1Etd+NVdCj7qWKUSN/bSLkZwhDv7I+w/MSC6qJ4cknepkAYykDdK8og==", + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.8.1.tgz", + "integrity": "sha512-OSs33Z9yWr148JZcbZd5WiAXhh/n9z8TxQcdMhIOlpN9AhWpLfvVFO73+m77bBABQMaY9XSvIa+qk0jlI7Gcaw==", "dev": true }, "node-int64": { @@ -22660,9 +22555,9 @@ "dev": true }, "nopt": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.0.tgz", - "integrity": "sha512-CVDtwCdhYIvnAzFoJ6NJ6dX3oga9/HyciQDnG1vQDjSLMeKLJ4A93ZqYKDrgYSr1FBY5/hMYC+2VCi24pgpkGA==", + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", "dev": true, "requires": { "abbrev": "^2.0.0" @@ -22993,9 +22888,9 @@ "dev": true }, "minipass-fetch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", - "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, "requires": { "encoding": "^0.1.13", @@ -23005,9 +22900,9 @@ }, "dependencies": { "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true } } @@ -23045,18 +22940,18 @@ } }, "ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "requires": { "minipass": "^7.0.3" }, "dependencies": { "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true } } @@ -23469,22 +23364,28 @@ }, "dependencies": { "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true } } }, "ignore-walk": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.4.tgz", - "integrity": "sha512-t7sv42WkwFkyKbivUCglsQW5YWMskWtbEf4MNKX5u/CCWHKSPzN4FtBQGsQZgCLbxOzpVlcbWVK5KB3auIOjSw==", + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-6.0.5.tgz", + "integrity": "sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==", "dev": true, "requires": { "minimatch": "^9.0.0" } }, + "json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true + }, "lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -23552,18 +23453,18 @@ } }, "ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "requires": { "minipass": "^7.0.3" }, "dependencies": { "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true } } @@ -23612,6 +23513,14 @@ "json-parse-even-better-errors": "^3.0.0", "just-diff": "^6.0.0", "just-diff-apply": "^5.2.0" + }, + "dependencies": { + "json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true + } } }, "parse-json": { @@ -23626,12 +23535,6 @@ "lines-and-columns": "^1.1.6" }, "dependencies": { - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, "lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -23693,9 +23596,9 @@ }, "dependencies": { "lru-cache": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.0.tgz", - "integrity": "sha512-2bIM8x+VAf6JT4bKAljS1qUWgMsqZRPGJS6FSahIMPVvctcNhyVp7AJu7quxOW9jwkryBReKZY5tY5JYv2n/7Q==", + "version": "10.2.2", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", + "integrity": "sha512-9hp3Vp2/hFQUiIwKo8XCeFVnrg8Pk3TYNPIR7tJADKi5YfcF7vEaK7avFHTlSy3kOKYaJQaalfEo6YuXdceBOQ==", "dev": true } } @@ -23860,7 +23763,8 @@ "punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", - "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==" + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true }, "pure-rand": { "version": "6.1.0", @@ -23950,12 +23854,6 @@ "lru-cache": "^7.5.1" } }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, "lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", @@ -24025,6 +23923,14 @@ "requires": { "json-parse-even-better-errors": "^3.0.0", "npm-normalize-package-bin": "^3.0.0" + }, + "dependencies": { + "json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true + } } }, "read-pkg": { @@ -24250,50 +24156,12 @@ "dev": true }, "rimraf": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-4.4.1.tgz", - "integrity": "sha512-Gk8NlF062+T9CqNGn6h4tls3k6T1+/nXdOcSZVikNVtlRdYpA7wRJJMoXmuvOnLW844rPjdQ7JgXCYM6PPC/og==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", "dev": true, "requires": { - "glob": "^9.2.0" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "glob": { - "version": "9.3.5", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", - "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" - } - }, - "minimatch": { - "version": "8.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", - "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - }, - "minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", - "dev": true - } + "glob": "^7.1.3" } }, "run-async": { @@ -24441,9 +24309,9 @@ "dev": true }, "minipass-fetch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", - "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, "requires": { "encoding": "^0.1.13", @@ -24453,26 +24321,26 @@ }, "dependencies": { "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true } } }, "ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "requires": { "minipass": "^7.0.3" }, "dependencies": { "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true } } @@ -24494,9 +24362,7 @@ "@typescript-eslint/parser": "^5.23.0", "eslint": "^8.15.0", "eslint-config-prettier": "^8.5.0", - "prettier": "^2.6.2", - "uri-js": "^4.4.1", - "valid-url": "^1.0.9" + "prettier": "^2.6.2" } }, "slash": { @@ -25073,9 +24939,9 @@ "dev": true }, "minipass-fetch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.4.tgz", - "integrity": "sha512-jHAqnA728uUpIaFm7NWsCnqKT6UqZz7GcI/bDpPATuwYyKwJwW0remxSCxUlKiEty+eopHGa3oc8WxgQ1FFJqg==", + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-3.0.5.tgz", + "integrity": "sha512-2N8elDQAtSnFV0Dk7gt15KHsS0Fyz6CbYZ360h0WTYV1Ty46li3rAXVOQj1THMNLdmrD9Vt5pBPtWtVkpwGBqg==", "dev": true, "requires": { "encoding": "^0.1.13", @@ -25085,26 +24951,26 @@ }, "dependencies": { "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true } } }, "ssri": { - "version": "10.0.5", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.5.tgz", - "integrity": "sha512-bSf16tAFkGeRlUNDjXu8FzaMQt6g2HZJrun7mtMbIPOddxt3GLMSz5VWUWcqTJUPfLEaDIepGxv+bYQW49596A==", + "version": "10.0.6", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-10.0.6.tgz", + "integrity": "sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==", "dev": true, "requires": { "minipass": "^7.0.3" }, "dependencies": { "minipass": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", - "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.0.tgz", + "integrity": "sha512-oGZRv2OT1lO2UF1zUcwdTb3wqUwI0kBGTgt/T7OdSj6M6N5m3o5uPf0AIW6lVxGGoiWUR7e2AwTE+xiwK8WQig==", "dev": true } } @@ -25249,6 +25115,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "requires": { "punycode": "^2.1.0" } @@ -25282,11 +25149,6 @@ "convert-source-map": "^2.0.0" } }, - "valid-url": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz", - "integrity": "sha512-QQDsV8OnSf5Uc30CKSwG9lnhMPe6exHtTXLRYX8uMwKENy640pU+2BgBL0LRbDh/eYRahNCS7aewCx0wf3NYVA==" - }, "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", diff --git a/packages/siwe-parser/lib/abnf.ts b/packages/siwe-parser/lib/abnf.ts index a7e5fcfa..b1db5dc2 100644 --- a/packages/siwe-parser/lib/abnf.ts +++ b/packages/siwe-parser/lib/abnf.ts @@ -1,366 +1,149 @@ -import apgApi from "apg-js/src/apg-api/api"; +import { grammar } from "./siwe-grammar"; +import { cb } from "./callbacks"; import apgLib from "apg-js/src/apg-lib/node-exports"; -import { isEIP55Address, parseIntegerNumber } from "./utils"; - -const GRAMMAR = ` -sign-in-with-ethereum = - [ scheme "://" ] domain %s" wants you to sign in with your Ethereum account:" LF - address LF - LF - [ statement LF ] - LF - %s"URI: " URI LF - %s"Version: " version LF - %s"Chain ID: " chain-id LF - %s"Nonce: " nonce LF - %s"Issued At: " issued-at - [ LF %s"Expiration Time: " expiration-time ] - [ LF %s"Not Before: " not-before ] - [ LF %s"Request ID: " request-id ] - [ LF %s"Resources:" - resources ] - -domain = authority - -address = "0x" 40*40HEXDIG - ; Must also conform to captilization - ; checksum encoding specified in EIP-55 - ; where applicable (EOAs). - -statement = 1*( reserved / unreserved / " " ) - ; The purpose is to exclude LF (line breaks). - -version = "1" - -nonce = 8*( ALPHA / DIGIT ) - -issued-at = date-time -expiration-time = date-time -not-before = date-time - -request-id = *pchar - -chain-id = 1*DIGIT - ; See EIP-155 for valid CHAIN_IDs. - -resources = *( LF resource ) - -resource = "- " URI - -; ------------------------------------------------------------------------------ -; RFC 3986 - -URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] - -hier-part = "//" authority path-abempty - / path-absolute - / path-rootless - / path-empty - -scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) - -authority = [ userinfo "@" ] host [ ":" port ] -userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) -host = IP-literal / IPv4address / reg-name -port = *DIGIT - -IP-literal = "[" ( IPv6address / IPvFuture ) "]" - -IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) - -IPv6address = 6( h16 ":" ) ls32 - / "::" 5( h16 ":" ) ls32 - / [ h16 ] "::" 4( h16 ":" ) ls32 - / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 - / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 - / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 - / [ *4( h16 ":" ) h16 ] "::" ls32 - / [ *5( h16 ":" ) h16 ] "::" h16 - / [ *6( h16 ":" ) h16 ] "::" - -h16 = 1*4HEXDIG -ls32 = ( h16 ":" h16 ) / IPv4address -IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet -dec-octet = DIGIT ; 0-9 - / %x31-39 DIGIT ; 10-99 - / "1" 2DIGIT ; 100-199 - / "2" %x30-34 DIGIT ; 200-249 - / "25" %x30-35 ; 250-255 - -reg-name = *( unreserved / pct-encoded / sub-delims ) - -path-abempty = *( "/" segment ) -path-absolute = "/" [ segment-nz *( "/" segment ) ] -path-rootless = segment-nz *( "/" segment ) -path-empty = 0pchar - -segment = *pchar -segment-nz = 1*pchar - -pchar = unreserved / pct-encoded / sub-delims / ":" / "@" - -query = *( pchar / "/" / "?" ) - -fragment = *( pchar / "/" / "?" ) - -pct-encoded = "%" HEXDIG HEXDIG - -unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" -reserved = gen-delims / sub-delims -gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" -sub-delims = "!" / "$" / "&" / "'" / "(" / ")" - / "*" / "+" / "," / ";" / "=" - -; ------------------------------------------------------------------------------ -; RFC 3339 - -date-fullyear = 4DIGIT -date-month = 2DIGIT ; 01-12 -date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on - ; month/year -time-hour = 2DIGIT ; 00-23 -time-minute = 2DIGIT ; 00-59 -time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second - ; rules -time-secfrac = "." 1*DIGIT -time-numoffset = ("+" / "-") time-hour ":" time-minute -time-offset = "Z" / time-numoffset - -partial-time = time-hour ":" time-minute ":" time-second - [time-secfrac] -full-date = date-fullyear "-" date-month "-" date-mday -full-time = partial-time time-offset - -date-time = full-date "T" full-time - -; ------------------------------------------------------------------------------ -; RFC 5234 - -ALPHA = %x41-5A / %x61-7A ; A-Z / a-z -LF = %x0A - ; linefeed -DIGIT = %x30-39 - ; 0-9 -HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" -`; - -class GrammarApi { - static grammarObj = this.generateApi(); - - static generateApi() { - const api = new apgApi(GRAMMAR); - api.generate(); - if (api.errors.length) { - console.error(api.errorsToAscii()); - console.error(api.linesToAscii()); - console.log(api.displayAttributeErrors()); - throw new Error(`ABNF grammar has errors`); - } - return api.toObject(); - } -} +const grammarObj = new grammar(); export class ParsedMessage { - scheme: string | null; - domain: string; - address: string; - statement: string | null; - uri: string; - version: string; - chainId: number; - nonce: string; - issuedAt: string; - expirationTime: string | null; - notBefore: string | null; - requestId: string | null; - resources: Array | null; - - constructor(msg: string) { - const parser = new apgLib.parser(); - parser.ast = new apgLib.ast(); - const id = apgLib.ids; - - const scheme = function (state, chars, phraseIndex, phraseLength, data) { - const ret = id.SEM_OK; - if (state === id.SEM_PRE && phraseIndex === 0) { - data.scheme = apgLib.utils.charsToString( - chars, - phraseIndex, - phraseLength - ); - } - return ret; - }; - parser.ast.callbacks.scheme = scheme; - - const domain = function (state, chars, phraseIndex, phraseLength, data) { - const ret = id.SEM_OK; - if (state === id.SEM_PRE) { - data.domain = apgLib.utils.charsToString( - chars, - phraseIndex, - phraseLength - ); - } - return ret; - }; - parser.ast.callbacks.domain = domain; - const address = function (state, chars, phraseIndex, phraseLength, data) { - const ret = id.SEM_OK; - if (state === id.SEM_PRE) { - data.address = apgLib.utils.charsToString( - chars, - phraseIndex, - phraseLength - ); - } - return ret; - }; - parser.ast.callbacks.address = address; - - const statement = function (state, chars, phraseIndex, phraseLength, data) { - const ret = id.SEM_OK; - if (state === id.SEM_PRE) { - data.statement = apgLib.utils.charsToString( - chars, - phraseIndex, - phraseLength - ); - } - return ret; - }; - parser.ast.callbacks.statement = statement; - const uri = function (state, chars, phraseIndex, phraseLength, data) { - const ret = id.SEM_OK; - if (state === id.SEM_PRE) { - if (!data.uri) { - data.uri = apgLib.utils.charsToString( - chars, - phraseIndex, - phraseLength - ); - } - } - return ret; - }; - parser.ast.callbacks.uri = uri; - const version = function (state, chars, phraseIndex, phraseLength, data) { - const ret = id.SEM_OK; - if (state === id.SEM_PRE) { - data.version = apgLib.utils.charsToString( - chars, - phraseIndex, - phraseLength - ); - } - return ret; - }; - parser.ast.callbacks.version = version; - const chainId = function (state, chars, phraseIndex, phraseLength, data) { - const ret = id.SEM_OK; - if (state === id.SEM_PRE) { - data.chainId = parseIntegerNumber( - apgLib.utils.charsToString(chars, phraseIndex, phraseLength) - ); - } - return ret; - }; - parser.ast.callbacks["chain-id"] = chainId; - const nonce = function (state, chars, phraseIndex, phraseLength, data) { - const ret = id.SEM_OK; - if (state === id.SEM_PRE) { - data.nonce = apgLib.utils.charsToString( - chars, - phraseIndex, - phraseLength - ); - } - return ret; - }; - parser.ast.callbacks.nonce = nonce; - const issuedAt = function (state, chars, phraseIndex, phraseLength, data) { - const ret = id.SEM_OK; - if (state === id.SEM_PRE) { - data.issuedAt = apgLib.utils.charsToString( - chars, - phraseIndex, - phraseLength - ); - } - return ret; - }; - parser.ast.callbacks["issued-at"] = issuedAt; - const expirationTime = function ( - state, - chars, - phraseIndex, - phraseLength, - data - ) { - const ret = id.SEM_OK; - if (state === id.SEM_PRE) { - data.expirationTime = apgLib.utils.charsToString( - chars, - phraseIndex, - phraseLength - ); - } - return ret; - }; - parser.ast.callbacks["expiration-time"] = expirationTime; - const notBefore = function (state, chars, phraseIndex, phraseLength, data) { - const ret = id.SEM_OK; - if (state === id.SEM_PRE) { - data.notBefore = apgLib.utils.charsToString( - chars, - phraseIndex, - phraseLength - ); - } - return ret; - }; - parser.ast.callbacks["not-before"] = notBefore; - const requestId = function (state, chars, phraseIndex, phraseLength, data) { - const ret = id.SEM_OK; - if (state === id.SEM_PRE) { - data.requestId = apgLib.utils.charsToString( - chars, - phraseIndex, - phraseLength - ); - } - return ret; - }; - parser.ast.callbacks["request-id"] = requestId; - const resources = function (state, chars, phraseIndex, phraseLength, data) { - const ret = id.SEM_OK; - if (state === id.SEM_PRE) { - data.resources = apgLib.utils - .charsToString(chars, phraseIndex, phraseLength) - .slice(3) - .split("\n- "); - } - return ret; - }; - parser.ast.callbacks.resources = resources; - - const result = parser.parse(GrammarApi.grammarObj, "sign-in-with-ethereum", msg); - if (!result.success) { - throw new Error(`Invalid message: ${JSON.stringify(result)}`); - } - const elements = {}; - parser.ast.translate(elements); - - for (const [key, value] of Object.entries(elements)) { - this[key] = value; - } - - if (this.domain.length === 0) { - throw new Error("Domain cannot be empty."); - } - - if (!isEIP55Address(this.address)) { - throw new Error("Address not conformant to EIP-55."); - } - } + scheme: string | undefined; + domain: string; + address: string; + statement: string | undefined; + uri: string; + version: string; + chainId: number; + nonce: string; + issuedAt: string; + expirationTime: string | undefined; + notBefore: string | undefined; + requestId: string | undefined; + resources: Array | undefined; + uriElements: { + scheme: string; + userinfo: string | undefined; + host: string | undefined; + port: string | undefined; + path: string; + query: string | undefined; + fragment: string | undefined; + }; + + // and display it on an HTML page. + constructor(msg: string) { + const parser = new apgLib.parser(); + parser.callbacks["sign-in-with-ethereum"] = cb.signInWithEtherium; + parser.callbacks["oscheme"] = cb.oscheme; + parser.callbacks["domain"] = cb.domain; + parser.callbacks["LF"] = cb.lineno; + parser.callbacks["ex-title"] = cb.exTitle; + parser.callbacks["nb-title"] = cb.nbTitle; + parser.callbacks["ri-title"] = cb.riTitle; + parser.callbacks["re-title"] = cb.reTitle; + parser.callbacks["address"] = cb.address; + parser.callbacks["statement"] = cb.statement; + parser.callbacks["empty-statement"] = cb.emptyStatement; + parser.callbacks["version"] = cb.version; + parser.callbacks["chain-id"] = cb.chainId; + parser.callbacks["nonce"] = cb.nonce; + parser.callbacks["issued-at"] = cb.issuedAt; + parser.callbacks["expiration-time"] = cb.expirationTime; + parser.callbacks["not-before"] = cb.notBefore; + parser.callbacks["request-id"] = cb.requestId; + parser.callbacks["uri"] = cb.uri; + parser.callbacks["uri-r"] = cb.uriR; + parser.callbacks["resource"] = cb.resource; + parser.callbacks["scheme"] = cb.scheme; + parser.callbacks["userinfo-at"] = cb.userinfo; + parser.callbacks["host"] = cb.host; + parser.callbacks["IP-literal"] = cb.ipLiteral; + parser.callbacks["port"] = cb.port; + parser.callbacks["path-abempty"] = cb.pathAbempty; + parser.callbacks["path-absolute"] = cb.pathAbsolute; + parser.callbacks["path-rootless"] = cb.pathRootless; + parser.callbacks["path-empty"] = cb.pathEmpty; + parser.callbacks["query"] = cb.query; + parser.callbacks["fragment"] = cb.fragment; + parser.callbacks["IPv4address"] = cb.ipv4; + parser.callbacks["nodcolon"] = cb.nodcolon; + parser.callbacks["dcolon"] = cb.dcolon; + parser.callbacks["h16"] = cb.h16; + parser.callbacks["h16c"] = cb.h16; + parser.callbacks["h16n"] = cb.h16; + parser.callbacks["h16cn"] = cb.h16; + parser.callbacks["dec-octet"] = cb.decOctet; + parser.callbacks["dec-digit"] = cb.decDigit; + + // initialize parsed elements + const elements = { + errors: [], + lineno: 1, + scheme: undefined, + domain: undefined, + address: undefined, + statement: undefined, + uri: undefined, + version: undefined, + chainId: undefined, + nonce: undefined, + issuedAt: undefined, + expirationTime: undefined, + notBefore: undefined, + requestId: undefined, + resources: undefined, + uriElements: { + scheme: undefined, + userinfo: undefined, + host: undefined, + port: undefined, + path: undefined, + query: undefined, + fragment: undefined, + }, + }; + + const result = parser.parse(grammarObj, 0, msg, elements); + let throwMsg = ""; + for (let i = 0; i < elements.errors.length; i += 1) { + throwMsg += elements.errors[i] + "\n"; + } + if (!result.success) { + throwMsg += `Invalid message: ${JSON.stringify(result)}`; + } + if (throwMsg !== "") { + throw new Error(throwMsg); + } + + this.scheme = elements.scheme; + this.domain = elements.domain; + this.address = elements.address; + this.statement = elements.statement; + this.uri = elements.uri; + this.version = elements.version; + this.chainId = elements.chainId; + this.nonce = elements.nonce; + this.issuedAt = elements.issuedAt; + this.expirationTime = elements.expirationTime; + this.notBefore = elements.notBefore; + this.requestId = elements.requestId; + this.resources = elements.resources; + this.uriElements = elements.uriElements; + } } + +export const isUri = (uri: string) => { + const parser = new apgLib.parser(); + parser.callbacks["IP-literal"] = cb.ipLiteral; + parser.callbacks["IPv4address"] = cb.ipv4; + parser.callbacks["nodcolon"] = cb.nodcolon; + parser.callbacks["dcolon"] = cb.dcolon; + parser.callbacks["h16"] = cb.h16; + parser.callbacks["h16c"] = cb.h16; + parser.callbacks["h16n"] = cb.h16; + parser.callbacks["h16cn"] = cb.h16; + parser.callbacks["dec-octet"] = cb.decOctet; + parser.callbacks["dec-digit"] = cb.decDigit; + + const data = { errors: [] }; + const result = parser.parse(grammarObj, "uri-r", uri, data); + + return result.success; +}; diff --git a/packages/siwe-parser/lib/callbacks.ts b/packages/siwe-parser/lib/callbacks.ts new file mode 100644 index 00000000..e4d4d147 --- /dev/null +++ b/packages/siwe-parser/lib/callbacks.ts @@ -0,0 +1,529 @@ +import apgLib from "apg-js/src/apg-lib/node-exports"; +const utils = apgLib.utils; +const id = apgLib.ids; +import { isEIP55Address, parseIntegerNumber } from "./utils"; + +/* copied from siwe/lib/utils.ts */ +const ISO8601 = + /^(?[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01]))[Tt]([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9]|60)(.[0-9]+)?(([Zz])|([+|-]([01][0-9]|2[0-3]):[0-5][0-9]))$/; +const isValidISO8601Date = (inputDate: string): boolean => { + /* Split groups and make sure inputDate is in ISO8601 format */ + const inputMatch = ISO8601.exec(inputDate); + + /* if inputMatch is null the date is not ISO-8601 */ + if (!inputMatch) { + return false; + } + + /* Creates a date object with input date to parse for invalid days e.g. Feb, 30 -> Mar, 01 */ + const inputDateParsed = new Date(inputMatch.groups.date).toISOString(); + + /* Get groups from new parsed date to compare with the original input */ + const parsedInputMatch = ISO8601.exec(inputDateParsed); + + /* Compare remaining fields */ + return inputMatch.groups.date === parsedInputMatch.groups.date; +}; + +export const cb = { + signInWithEtherium: function (result, chars, phraseIndex, data) { + switch (result.state) { + case id.ACTIVE: + if (typeof data !== "object" || data === null) { + throw new Error("data must be an object"); + } + break; + case id.NOMATCH: + data.errors.push(`invalid message: max line number was ${data.lineno}`); + } + }, + lineno: function lineno(result, chars, phraseIndex, data) { + if (result.state === id.MATCH) { + data.lineno += 1; + } + }, + exTitle: function exTitle(result, chars, phraseIndex, data) { + if (result.state === id.NOMATCH) { + data.lineno -= 1; + } + }, + nbTitle: function nbTitle(result, chars, phraseIndex, data) { + if (result.state === id.NOMATCH) { + data.lineno -= 1; + } + }, + riTitle: function riTitle(result, chars, phraseIndex, data) { + if (result.state === id.NOMATCH) { + data.lineno -= 1; + } + }, + reTitle: function reTitle(result, chars, phraseIndex, data) { + if (result.state === id.MATCH) { + data.resources = []; + } else if (result.state === id.NOMATCH) { + data.lineno -= 1; + } + }, + oscheme: function oscheme(result, chars, phraseIndex, data) { + if (result.state === id.MATCH) { + // if matched, remove :// from oscheme + data.scheme = utils.charsToString( + chars, + phraseIndex, + result.phraseLength - 3 + ); + } + }, + domain: function domain(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.domain = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + break; + case id.EMPTY: + data.errors.push(`line ${data.lineno}: domain cannot be empty`); + break; + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid domain`); + } + }, + address: function address(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.address = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + if (!isEIP55Address(data.address)) { + data.errors.push( + `line ${data.lineno}: invalid EIP-55 address - ${data.address}` + ); + } + break; + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid address`); + break; + } + }, + statement: function statement(result, chars, phraseIndex, data) { + if (result.state === id.MATCH) { + data.statement = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + } + }, + emptyStatement: function emptyStatement(result, chars, phraseIndex, data) { + if (result.state === id.MATCH) { + data.statement = ""; + } + }, + version: function version(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.version = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + break; + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid version`); + break; + } + }, + nonce: function nonce(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.nonce = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + break; + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid nonce`); + break; + } + }, + issuedAt: function issuedAt(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.issuedAt = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + if (!isValidISO8601Date(data.issuedAt)) { + data.errors.push( + `line ${data.lineno}: invalid issued-at date time semantics` + ); + } + break; + case id.NOMATCH: + data.errors.push( + `line ${data.lineno}: invalid issued-at date time syntax` + ); + break; + } + }, + expirationTime: function expirationTime(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.expirationTime = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + if (!isValidISO8601Date(data.expirationTime)) { + data.errors.push( + `line ${data.lineno}: invalid expiration-time date time semantics` + ); + } + break; + case id.NOMATCH: + data.errors.push( + `line ${data.lineno}: invalid expiration-time date time syntax` + ); + break; + } + }, + notBefore: function notBefore(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.notBefore = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + if (!isValidISO8601Date(data.notBefore)) { + data.errors.push( + `line ${data.lineno}: invalid not-before date time semantics` + ); + } + break; + case id.NOMATCH: + data.errors.push( + `line ${data.lineno}: invalid not-before date time syntax` + ); + break; + } + }, + requestId: function requestId(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.requestId = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + break; + case id.EMPTY: + data.requestId = ""; + break; + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid requestID`); + break; + } + }, + chainId: function chainId(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.chainId = parseIntegerNumber( + utils.charsToString(chars, phraseIndex, result.phraseLength) + ); + break; + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid chain-id`); + break; + } + }, + uriR: function uriR(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.uriR = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + break; + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid resource URI`); + break; + } + }, + resource: function resource(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.resources.push(data.uriR); + delete data.uriR; + break; + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid resource`); + break; + } + }, + // handle the URI + scheme: function scheme(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.uriElements.scheme = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + break; + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid URI scheme`); + break; + } + }, + userinfo: function userinfo(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.uriElements.userinfo = utils.charsToString( + chars, + phraseIndex, + result.phraseLength - 1 + ); + break; + } + }, + host: function host(result, chars, phraseIndex, data) { + switch (result.state) { + case id.ACTIVE: + data.iplit = false; + break; + case id.MATCH: + if (data.iplit) { + // strip leading "[" and trailing "]" brackets + data.uriElements.host = utils.charsToString( + chars, + phraseIndex + 1, + result.phraseLength - 2 + ); + } else { + data.uriElements.host = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + } + break; + case id.EMPTY: + data.uriElements.host = ""; + break; + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid URI host`); + break; + } + }, + ipLiteral: function ipLiteral(result, chars, phraseIndex, data) { + if (result.state === id.MATCH) { + data.iplit = true; + } + }, + port: function port(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.uriElements.port = parseIntegerNumber( + utils.charsToString(chars, phraseIndex, result.phraseLength) + ); + break; + case id.EMPTY: + data.uriElements.port = ""; + break; + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid URI port`); + break; + } + }, + pathAbempty: function pathAbempty(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.uriElements.path = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + break; + case id.EMPTY: + data.uriElements.path = ""; + break; + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid URI path-abempty`); + break; + } + }, + pathAbsolute: function pathAbsolute(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.uriElements.path = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + break; + } + }, + pathRootless: function pathRootless(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.uriElements.path = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + break; + } + }, + pathEmpty: function pathEmpty(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + case id.NOMATCH: + data.errors.push( + `line ${data.lineno}: invalid URI - path-empty must be empty` + ); + break; + case id.EMPTY: + data.uriElements.path = ""; + break; + } + }, + query: function query(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.uriElements.query = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + break; + case id.EMPTY: + data.uriElements.query = ""; + break; + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid URI query`); + break; + } + }, + fragment: function fragment(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.uriElements.fragment = utils.charsToString( + chars, + phraseIndex, + result.phraseLength + ); + break; + case id.EMPTY: + data.uriElements.fragment = ""; + break; + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid URI fragment`); + break; + } + }, + uri: function URI(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + //NOTE: all "valid-url" tests are satisfied if URI ABNF parses without error. + data.uri = utils.charsToString(chars, phraseIndex, result.phraseLength); + break; + case id.EMPTY: + case id.NOMATCH: + data.errors.push(`line ${data.lineno}: invalid URI`); + break; + } + }, + ipv4: function ipv4(result, chars, phraseIndex, data) { + if (result.state === id.MATCH) { + data.ipv4 = true; + } + }, + h16: function h16(result, chars, phraseIndex, data) { + if (result.state === id.MATCH) { + data.h16count += 1; + } + }, + nodcolon: function nodcolon(result, chars, phraseIndex, data) { + switch (result.state) { + case id.ACTIVE: + data.h16count = 0; + data.ipv4 = false; + break; + case id.MATCH: + // semantically validate the number of 16-bit digits + if (data.ipv4) { + if (data.h16count === 6) { + result.state = id.MATCH; + } else { + result.state = id.NOMATCH; + result.phraseLength = 0; + } + } else { + if (data.h16count === 8) { + result.state = id.MATCH; + } else { + result.state = id.NOMATCH; + result.phraseLength = 0; + } + } + break; + } + }, + dcolon: function dcolon(result, chars, phraseIndex, data) { + switch (result.state) { + case id.ACTIVE: + data.h16count = 0; + data.ipv4 = false; + break; + case id.MATCH: + // semantically validate the number of 16-bit digits + if (data.ipv4) { + if (data.h16count < 6) { + result.state = id.MATCH; + } else { + result.state = id.NOMATCH; + result.phraseLength = 0; + } + } else { + if (data.h16count < 8) { + result.state = id.MATCH; + } else { + result.state = id.NOMATCH; + result.phraseLength = 0; + } + } + break; + } + }, + decOctet: function decOctet(result, chars, phraseIndex, data) { + switch (result.state) { + case id.ACTIVE: + data.octet = 0; + break; + case id.MATCH: + // semantically validate the octet + if (data.octet > 255) { + result.state = id.NOMATCH; + result.phraseLength = 0; + } else { + result.state = id.MATCH; + } + break; + } + }, + decDigit: function decDigit(result, chars, phraseIndex, data) { + switch (result.state) { + case id.MATCH: + data.octet = 10 * data.octet + chars[phraseIndex] - 48; + break; + } + }, +}; diff --git a/packages/siwe-parser/lib/parsers.test.ts b/packages/siwe-parser/lib/parsers.test.ts index 3b362a0b..cd11c745 100644 --- a/packages/siwe-parser/lib/parsers.test.ts +++ b/packages/siwe-parser/lib/parsers.test.ts @@ -1,34 +1,37 @@ import { ParsedMessage } from "./abnf"; import * as fs from "fs"; -const parsingPositive: object = JSON.parse(fs.readFileSync('../../test/parsing_positive.json', 'utf8')); -const parsingNegative: object = JSON.parse(fs.readFileSync('../../test/parsing_negative.json', 'utf8')); +const parsingPositive: object = JSON.parse( + fs.readFileSync("../../test/parsing_positive.json", "utf8") +); +const parsingNegative: object = JSON.parse( + fs.readFileSync("../../test/parsing_negative.json", "utf8") +); // describe("Successfully parses with ABNF Client", () => { - test.concurrent.each(Object.entries(parsingPositive))( - "Parses message successfully: %s", - (test_name, test) => { - const parsedMessage = new ParsedMessage(test.message); - for (const [field, value] of Object.entries(test.fields)) { - if (value === null) { - expect(parsedMessage[field]).toBeUndefined(); - } - else if (typeof value === "object") { - expect(parsedMessage[field]).toStrictEqual(value); - } else { - expect(parsedMessage[field]).toBe(value); - } - } - } - ); + test.concurrent.each(Object.entries(parsingPositive))( + "Parses message successfully: %s", + (test_name, test) => { + const parsedMessage = new ParsedMessage(test.message); + for (const [field, value] of Object.entries(test.fields)) { + if (value === null) { + expect(parsedMessage[field]).toBeUndefined(); + } else if (typeof value === "object") { + expect(parsedMessage[field]).toStrictEqual(value); + } else { + expect(parsedMessage[field]).toBe(value); + } + } + } + ); }); describe("Successfully fails with ABNF Client", () => { - test.concurrent.each(Object.entries(parsingNegative))( - "Fails to parse message: %s", - (test_name, test) => { - expect(() => new ParsedMessage(test)).toThrow(); - } - ); + test.concurrent.each(Object.entries(parsingNegative))( + "Fails to parse message: %s", + (test_name, test) => { + expect(() => new ParsedMessage(test)).toThrow(); + } + ); }); diff --git a/packages/siwe-parser/lib/parsers.ts b/packages/siwe-parser/lib/parsers.ts index 815fd402..bed3b575 100644 --- a/packages/siwe-parser/lib/parsers.ts +++ b/packages/siwe-parser/lib/parsers.ts @@ -1,7 +1,5 @@ import { ParsedMessage as ABNFParsedMessage } from "./abnf"; -export * from './utils'; -export { - ABNFParsedMessage as ParsedMessage -}; - - +import { isUri as ABNFisUri } from "./abnf"; +export * from "./utils"; +export { ABNFParsedMessage as ParsedMessage }; +export { ABNFisUri as isUri }; diff --git a/packages/siwe-parser/lib/siwe-abnf.txt b/packages/siwe-parser/lib/siwe-abnf.txt new file mode 100644 index 00000000..b8076aa2 --- /dev/null +++ b/packages/siwe-parser/lib/siwe-abnf.txt @@ -0,0 +1,212 @@ +; LDT 05/06/2024 +; modified in several significant ways +; 1) Literal strings are replaced with numbers and ranges (%d32 & %d32-126, etc.) when possible. +; TRB and especially TRG operators are much more efficient than TLS operators. +; 2) Two rules, authority and URI, are used multiple times in different contexts. These rules will be reproduced and renamed +; in order to a) recognize the context and b) remove unneccary callback functions for certain contexts. +; This will simiplify recognizing contexts AND remove unneccesary callbacks +; 2.a) domain is defined as authority-d which is identical to authority except that there will be no +; callback functions defined on authority-d or any of its *-d components. +; 2.b) The resource URI is defined as URI-r and its components defined as *-r. +; In this way, callback functions can be defined on URI and is components while +; leaving URI-r to be parsed identically with no unnecessary callback functions to slow it down. +; 3) IPv6address does not work because of APG's "first-success disambiguation" and "greedy" repetitions. +; IPv6address redefined and validations moved to callback functions (semantic vs syntactic validation) +; Redefinition requires negative look-ahead operators, https://en.wikipedia.org/wiki/Syntactic_predicate +; That is SABNF instead of simple ABNF. +; 4) IPv4address fails because of "first-success disambiguation". +; This could be fixed with rearrangement of the alternative terms. However, it would still not +; accept zero-padded (leading zeros) decimal octets. +; Therefore, IPv4address is also done with callback functions and semantic validation. +; 5) The negative look-ahead operator is also needed in the definition of host to +; prevent failure with a reg-name that begins with an IPv4 address. +; 6) NOTE: host = 1.1.1.256 is a valid host name even though it is an invalid IPv4address. +; The IPv4address alternative fails but the reg-name alternative succeeds. +; 7) The Ethereum spec (https://eips.ethereum.org/EIPS/eip-4361) message format ABNF +; allows for empty statements. Because of the "first success disambiguation" of APG +; the an explicit "empty-statement" rule is required to match the spec's intent. + + +sign-in-with-ethereum = + oscheme domain %s" wants you to sign in with your Ethereum account:" LF + address LF + ((LF statement LF LF) / empty-statement / (LF LF)) + %s"URI: " URI LF + %s"Version: " version LF + %s"Chain ID: " chain-id LF + %s"Nonce: " nonce LF + %s"Issued At: " issued-at + [ LF ex-title expiration-time ] + [ LF nb-title not-before ] + [ LF ri-title request-id ] + [ LF re-title resources ] +ex-title = %s"Expiration Time: " +nb-title = %s"Not Before: " +ri-title = %s"Request ID: " +re-title = %s"Resources:" +oscheme = [ ALPHA *( ALPHA / DIGIT / %d43 / %d45-46 ) "://" ] +domain = authority-d +address = "0x" 40*40HEXDIG + ; Must also conform to captilization + ; checksum encoding specified in EIP-55 + ; where applicable (EOAs). + +statement = 1*( %d97-122 / %d65-90 / %d48-57 / %d32-33 / %d35-36 / %d38-59 / %d61 / %d63-64 / %d91 / %d93 / %d95 / %d126) + ; The purpose is to exclude LF (line breaks). + ; LDT 10/04/2023: Do you mean %d32-126? All printing characters +empty-statement = LF LF LF +version = "1" +nonce = 8*( ALPHA / DIGIT ) +issued-at = date-time +expiration-time = date-time +not-before = date-time +request-id = *pchar +chain-id = 1*DIGIT + ; See EIP-155 for valid CHAIN_IDs. +resources = *( LF resource ) +resource = "- " URI-r + +; ------------------------------------------------------------------------------ +; RFC 3986 + +URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] +hier-part = "//" authority path-abempty + / path-absolute + / path-rootless + / path-empty +scheme = ALPHA *( ALPHA / DIGIT / %d43 / %d45-46 ) +authority = [ userinfo-at ] host [ ":" port ] +path-abempty = *( "/" segment ) +path-absolute = "/" [ segment-nz *( "/" segment ) ] +path-rootless = segment-nz *( "/" segment ) +path-empty = "" +userinfo-at = userinfo %d64 + ; userinfo redefined to include the "@" so that it will fail without it + ; otherwise userinfo can match host and then the parser will backtrack + ; incorrectly keeping the captured userinfo phrase +userinfo = *(%d97-122 / %d65-90 / %d48-57 / pct-encoded / %d33 / %d36 / %d38-46 / %d58-59 / %d61 / %d95 / %d126) +host = IP-literal / (IPv4address !reg-name-char) / reg-name + ; negative look-ahead required to prevent IPv4address from being recognized as first part of reg-name + ; same fix as https://github.com/garycourt/uri-js/issues/4 +IP-literal = "[" ( IPv6address / IPvFuture ) "]" +IPvFuture = "v" 1*HEXDIG "." 1*( %d97-122 / %d65-90 / %d48-57 / %d33 / %d36 /%d38-46 / %d58-59 /%d61 /%d95 / %d126 ) +IPv6address = nodcolon / dcolon +nodcolon = (h16n *h16cn) [%d58 IPv4address] +dcolon = [h16 *h16c] %d58.58 (((h16n *h16cn) [%d58 IPv4address]) / [IPv4address]) +h16 = 1*4HEXDIG +h16c = %d58 1*4HEXDIG +h16n = 1*4HEXDIG !%d46 +h16cn = %d58 1*4HEXDIG !%d46 +IPv4address = dec-octet "." dec-octet "." dec-octet "." dec-octet +; Here we will will use callback functions to evaluate and validate the (possibly zero-padded) dec-octet. +dec-octet = *3dec-digit +dec-digit = %d48-57 +reg-name = *reg-name-char +reg-name-char = %d97-122 / %d65-90 / %d48-57 / pct-encoded / %d33 / %d36 / %d38-46 / %d59 / %d61 /%d95 / %d126 +port = *DIGIT +query = *(pchar / %d47 / %d63) +fragment = *(pchar / %d47 / %d63) + +; URI-r is a redefiniton of URI but without the callback functions attached to it +; it reuses athority-d from domain +URI-r = scheme-r ":" hier-part-r [ "?" query-r ] [ "#" fragment-r ] +hier-part-r = "//" authority-d path-abempty-r + / path-absolute-r + / path-rootless-r + / path-empty-r +scheme-r = ALPHA *( ALPHA / DIGIT / %d43 / %d45-46 ) +query-r = *(pchar / %d47 / %d63) +fragment-r = *(pchar / %d47 / %d63) + +; authority-d is a redefinition of authority for capturing the domian phrase +; but without callback functions +; it is reused for URI- for the same reason +authority-d = [ userinfo-d %d64 ] host-d [ ":" port-d ] +userinfo-d = *(%d97-122 / %d65-90 / %d48-57 / pct-encoded / %d33 / %d36 / %d38-46 / %d58-59 / %d61 / %d95 / %d126) +host-d = IP-literal / (IPv4address !reg-name-char) / reg-name +port-d = *DIGIT + +; for use with URI-r +path-abempty-r = *( "/" segment ) +path-absolute-r = "/" [ segment-nz *( "/" segment ) ] +path-rootless-r = segment-nz *( "/" segment ) +path-empty-r = "" +segment = *pchar +segment-nz = 1*pchar +pchar = (%d97-122 / %d65-90 / %d48-57 / pct-encoded / %d33 / %d36 / %d38-46 /%d58-59 / %d61 / %d64 / %d95 / %d126) +pct-encoded = %d37 HEXDIG HEXDIG + +; no longer needed - expanded for all usage for fewer branches in the parse there +; and more efficient use of the TBS & TRG operators in place of TLS and rule names +; does not work with APG probably because of "first-success disambiguation" and greedy repetitions. +; will replace with semantic checking of valid number of h16s +;IPv6address = 6( h16 ":" ) ls32 +; / "::" 5( h16 ":" ) ls32 +; / [ h16 ] "::" 4( h16 ":" ) ls32 +; / [ *1( h16 ":" ) h16 ] "::" 3( h16 ":" ) ls32 +; / [ *2( h16 ":" ) h16 ] "::" 2( h16 ":" ) ls32 +; / [ *3( h16 ":" ) h16 ] "::" h16 ":" ls32 +; / [ *4( h16 ":" ) h16 ] "::" ls32 +; / [ *5( h16 ":" ) h16 ] "::" h16 +; / [ *6( h16 ":" ) h16 ] "::" +;ls32 = ( h16 ":" h16 ) / IPv4address +; dec-octet does not work because of "first-success disambiguation". +; Must have the longest (3-digit) numbers first. +; Even so, this form does not accept leading zeros. +; There does not seem to be a clear standard for this (https://en.wikipedia.org/wiki/Dot-decimal_notation) +; however and early RFC 790 did show leading-zero padding of the three digits. +;dec-octet = DIGIT ; 0-9 +; / %x31-39 DIGIT ; 10-99 +; / "1" 2DIGIT ; 100-199 +; / "2" %x30-34 DIGIT ; 200-249 +; / "25" %x30-35 ; 250-255 +;statement = 1*( reserved / unreserved / " " ) +;scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." ) +;authority = [ userinfo "@" ] host [ ":" port ] +;userinfo = *( unreserved / pct-encoded / sub-delims / ":" ) +;query = *( pchar / "/" / "?" ) +;fragment = *( pchar / "/" / "?" ) +;IPvFuture = "v" 1*HEXDIG "." 1*( unreserved / sub-delims / ":" ) +;reg-name = *( unreserved / pct-encoded / sub-delims ) +;pct-encoded = "%" HEXDIG HEXDIG +;pchar = unreserved / pct-encoded / sub-delims / ":" / "@" +;path-empty = 0pchar; deprecated - empty literal string, "", is more efficient +;unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~" +;reserved = gen-delims / sub-delims +;gen-delims = ":" / "/" / "?" / "#" / "[" / "]" / "@" +;sub-delims = "!" / "$" / "&" / "'" / "(" / ")" +; / "*" / "+" / "," / ";" / "=" +;HEXDIG = DIGIT / "A" / "B" / "C" / "D" / "E" / "F" + +; ------------------------------------------------------------------------------ +; RFC 3339 + +date-fullyear = 4DIGIT +date-month = 2DIGIT ; 01-12 +date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on + ; month/year +time-hour = 2DIGIT ; 00-23 +time-minute = 2DIGIT ; 00-59 +time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second + ; rules +time-secfrac = "." 1*DIGIT +time-numoffset = ("+" / "-") time-hour ":" time-minute +time-offset = "Z" / time-numoffset + +partial-time = time-hour ":" time-minute ":" time-second + [time-secfrac] +full-date = date-fullyear "-" date-month "-" date-mday +full-time = partial-time time-offset + +date-time = full-date "T" full-time + +; ------------------------------------------------------------------------------ +; RFC 5234 + +ALPHA = %x41-5A / %x61-7A ; A-Z / a-z +LF = %x0A + ; linefeed +DIGIT = %x30-39 + ; 0-9 +HEXDIG = %d48-57 / %d65-70 / %d97-102 + diff --git a/packages/siwe-parser/lib/siwe-grammar.ts b/packages/siwe-parser/lib/siwe-grammar.ts new file mode 100644 index 00000000..0a92aa0e --- /dev/null +++ b/packages/siwe-parser/lib/siwe-grammar.ts @@ -0,0 +1,1042 @@ +// copyright: Copyright (c) 2024 Lowell D. Thomas, all rights reserved
+// license: BSD-2-Clause (https://opensource.org/licenses/BSD-2-Clause)
+// +// Generated by apg-js, Version 4.4.0 [apg-js](https://github.com/ldthomas/apg-js) +export function grammar(){ + // ``` + // SUMMARY + // rules = 81 + // udts = 0 + // opcodes = 461 + // --- ABNF original opcodes + // ALT = 26 + // CAT = 63 + // REP = 63 + // RNM = 159 + // TLS = 41 + // TBS = 64 + // TRG = 41 + // --- SABNF superset opcodes + // UDT = 0 + // AND = 0 + // NOT = 4 + // BKA = 0 + // BKN = 0 + // BKR = 0 + // ABG = 0 + // AEN = 0 + // characters = [10 - 126] + // ``` + /* OBJECT IDENTIFIER (for internal parser use) */ + this.grammarObject = 'grammarObject'; + + /* RULES */ + this.rules = []; + this.rules[0] = { name: 'sign-in-with-ethereum', lower: 'sign-in-with-ethereum', index: 0, isBkr: false }; + this.rules[1] = { name: 'ex-title', lower: 'ex-title', index: 1, isBkr: false }; + this.rules[2] = { name: 'nb-title', lower: 'nb-title', index: 2, isBkr: false }; + this.rules[3] = { name: 'ri-title', lower: 'ri-title', index: 3, isBkr: false }; + this.rules[4] = { name: 're-title', lower: 're-title', index: 4, isBkr: false }; + this.rules[5] = { name: 'oscheme', lower: 'oscheme', index: 5, isBkr: false }; + this.rules[6] = { name: 'domain', lower: 'domain', index: 6, isBkr: false }; + this.rules[7] = { name: 'address', lower: 'address', index: 7, isBkr: false }; + this.rules[8] = { name: 'statement', lower: 'statement', index: 8, isBkr: false }; + this.rules[9] = { name: 'empty-statement', lower: 'empty-statement', index: 9, isBkr: false }; + this.rules[10] = { name: 'version', lower: 'version', index: 10, isBkr: false }; + this.rules[11] = { name: 'nonce', lower: 'nonce', index: 11, isBkr: false }; + this.rules[12] = { name: 'issued-at', lower: 'issued-at', index: 12, isBkr: false }; + this.rules[13] = { name: 'expiration-time', lower: 'expiration-time', index: 13, isBkr: false }; + this.rules[14] = { name: 'not-before', lower: 'not-before', index: 14, isBkr: false }; + this.rules[15] = { name: 'request-id', lower: 'request-id', index: 15, isBkr: false }; + this.rules[16] = { name: 'chain-id', lower: 'chain-id', index: 16, isBkr: false }; + this.rules[17] = { name: 'resources', lower: 'resources', index: 17, isBkr: false }; + this.rules[18] = { name: 'resource', lower: 'resource', index: 18, isBkr: false }; + this.rules[19] = { name: 'URI', lower: 'uri', index: 19, isBkr: false }; + this.rules[20] = { name: 'hier-part', lower: 'hier-part', index: 20, isBkr: false }; + this.rules[21] = { name: 'scheme', lower: 'scheme', index: 21, isBkr: false }; + this.rules[22] = { name: 'authority', lower: 'authority', index: 22, isBkr: false }; + this.rules[23] = { name: 'path-abempty', lower: 'path-abempty', index: 23, isBkr: false }; + this.rules[24] = { name: 'path-absolute', lower: 'path-absolute', index: 24, isBkr: false }; + this.rules[25] = { name: 'path-rootless', lower: 'path-rootless', index: 25, isBkr: false }; + this.rules[26] = { name: 'path-empty', lower: 'path-empty', index: 26, isBkr: false }; + this.rules[27] = { name: 'userinfo-at', lower: 'userinfo-at', index: 27, isBkr: false }; + this.rules[28] = { name: 'userinfo', lower: 'userinfo', index: 28, isBkr: false }; + this.rules[29] = { name: 'host', lower: 'host', index: 29, isBkr: false }; + this.rules[30] = { name: 'IP-literal', lower: 'ip-literal', index: 30, isBkr: false }; + this.rules[31] = { name: 'IPvFuture', lower: 'ipvfuture', index: 31, isBkr: false }; + this.rules[32] = { name: 'IPv6address', lower: 'ipv6address', index: 32, isBkr: false }; + this.rules[33] = { name: 'nodcolon', lower: 'nodcolon', index: 33, isBkr: false }; + this.rules[34] = { name: 'dcolon', lower: 'dcolon', index: 34, isBkr: false }; + this.rules[35] = { name: 'h16', lower: 'h16', index: 35, isBkr: false }; + this.rules[36] = { name: 'h16c', lower: 'h16c', index: 36, isBkr: false }; + this.rules[37] = { name: 'h16n', lower: 'h16n', index: 37, isBkr: false }; + this.rules[38] = { name: 'h16cn', lower: 'h16cn', index: 38, isBkr: false }; + this.rules[39] = { name: 'IPv4address', lower: 'ipv4address', index: 39, isBkr: false }; + this.rules[40] = { name: 'dec-octet', lower: 'dec-octet', index: 40, isBkr: false }; + this.rules[41] = { name: 'dec-digit', lower: 'dec-digit', index: 41, isBkr: false }; + this.rules[42] = { name: 'reg-name', lower: 'reg-name', index: 42, isBkr: false }; + this.rules[43] = { name: 'reg-name-char', lower: 'reg-name-char', index: 43, isBkr: false }; + this.rules[44] = { name: 'port', lower: 'port', index: 44, isBkr: false }; + this.rules[45] = { name: 'query', lower: 'query', index: 45, isBkr: false }; + this.rules[46] = { name: 'fragment', lower: 'fragment', index: 46, isBkr: false }; + this.rules[47] = { name: 'URI-r', lower: 'uri-r', index: 47, isBkr: false }; + this.rules[48] = { name: 'hier-part-r', lower: 'hier-part-r', index: 48, isBkr: false }; + this.rules[49] = { name: 'scheme-r', lower: 'scheme-r', index: 49, isBkr: false }; + this.rules[50] = { name: 'query-r', lower: 'query-r', index: 50, isBkr: false }; + this.rules[51] = { name: 'fragment-r', lower: 'fragment-r', index: 51, isBkr: false }; + this.rules[52] = { name: 'authority-d', lower: 'authority-d', index: 52, isBkr: false }; + this.rules[53] = { name: 'userinfo-d', lower: 'userinfo-d', index: 53, isBkr: false }; + this.rules[54] = { name: 'host-d', lower: 'host-d', index: 54, isBkr: false }; + this.rules[55] = { name: 'port-d', lower: 'port-d', index: 55, isBkr: false }; + this.rules[56] = { name: 'path-abempty-r', lower: 'path-abempty-r', index: 56, isBkr: false }; + this.rules[57] = { name: 'path-absolute-r', lower: 'path-absolute-r', index: 57, isBkr: false }; + this.rules[58] = { name: 'path-rootless-r', lower: 'path-rootless-r', index: 58, isBkr: false }; + this.rules[59] = { name: 'path-empty-r', lower: 'path-empty-r', index: 59, isBkr: false }; + this.rules[60] = { name: 'segment', lower: 'segment', index: 60, isBkr: false }; + this.rules[61] = { name: 'segment-nz', lower: 'segment-nz', index: 61, isBkr: false }; + this.rules[62] = { name: 'pchar', lower: 'pchar', index: 62, isBkr: false }; + this.rules[63] = { name: 'pct-encoded', lower: 'pct-encoded', index: 63, isBkr: false }; + this.rules[64] = { name: 'date-fullyear', lower: 'date-fullyear', index: 64, isBkr: false }; + this.rules[65] = { name: 'date-month', lower: 'date-month', index: 65, isBkr: false }; + this.rules[66] = { name: 'date-mday', lower: 'date-mday', index: 66, isBkr: false }; + this.rules[67] = { name: 'time-hour', lower: 'time-hour', index: 67, isBkr: false }; + this.rules[68] = { name: 'time-minute', lower: 'time-minute', index: 68, isBkr: false }; + this.rules[69] = { name: 'time-second', lower: 'time-second', index: 69, isBkr: false }; + this.rules[70] = { name: 'time-secfrac', lower: 'time-secfrac', index: 70, isBkr: false }; + this.rules[71] = { name: 'time-numoffset', lower: 'time-numoffset', index: 71, isBkr: false }; + this.rules[72] = { name: 'time-offset', lower: 'time-offset', index: 72, isBkr: false }; + this.rules[73] = { name: 'partial-time', lower: 'partial-time', index: 73, isBkr: false }; + this.rules[74] = { name: 'full-date', lower: 'full-date', index: 74, isBkr: false }; + this.rules[75] = { name: 'full-time', lower: 'full-time', index: 75, isBkr: false }; + this.rules[76] = { name: 'date-time', lower: 'date-time', index: 76, isBkr: false }; + this.rules[77] = { name: 'ALPHA', lower: 'alpha', index: 77, isBkr: false }; + this.rules[78] = { name: 'LF', lower: 'lf', index: 78, isBkr: false }; + this.rules[79] = { name: 'DIGIT', lower: 'digit', index: 79, isBkr: false }; + this.rules[80] = { name: 'HEXDIG', lower: 'hexdig', index: 80, isBkr: false }; + + /* UDTS */ + this.udts = []; + + /* OPCODES */ + /* sign-in-with-ethereum */ + this.rules[0].opcodes = []; + this.rules[0].opcodes[0] = { type: 2, children: [1,2,3,4,5,6,7,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,36,41,46] };// CAT + this.rules[0].opcodes[1] = { type: 4, index: 5 };// RNM(oscheme) + this.rules[0].opcodes[2] = { type: 4, index: 6 };// RNM(domain) + this.rules[0].opcodes[3] = { type: 6, string: [32,119,97,110,116,115,32,121,111,117,32,116,111,32,115,105,103,110,32,105,110,32,119,105,116,104,32,121,111,117,114,32,69,116,104,101,114,101,117,109,32,97,99,99,111,117,110,116,58] };// TBS + this.rules[0].opcodes[4] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[5] = { type: 4, index: 7 };// RNM(address) + this.rules[0].opcodes[6] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[7] = { type: 1, children: [8,13,14] };// ALT + this.rules[0].opcodes[8] = { type: 2, children: [9,10,11,12] };// CAT + this.rules[0].opcodes[9] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[10] = { type: 4, index: 8 };// RNM(statement) + this.rules[0].opcodes[11] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[12] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[13] = { type: 4, index: 9 };// RNM(empty-statement) + this.rules[0].opcodes[14] = { type: 2, children: [15,16] };// CAT + this.rules[0].opcodes[15] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[16] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[17] = { type: 6, string: [85,82,73,58,32] };// TBS + this.rules[0].opcodes[18] = { type: 4, index: 19 };// RNM(URI) + this.rules[0].opcodes[19] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[20] = { type: 6, string: [86,101,114,115,105,111,110,58,32] };// TBS + this.rules[0].opcodes[21] = { type: 4, index: 10 };// RNM(version) + this.rules[0].opcodes[22] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[23] = { type: 6, string: [67,104,97,105,110,32,73,68,58,32] };// TBS + this.rules[0].opcodes[24] = { type: 4, index: 16 };// RNM(chain-id) + this.rules[0].opcodes[25] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[26] = { type: 6, string: [78,111,110,99,101,58,32] };// TBS + this.rules[0].opcodes[27] = { type: 4, index: 11 };// RNM(nonce) + this.rules[0].opcodes[28] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[29] = { type: 6, string: [73,115,115,117,101,100,32,65,116,58,32] };// TBS + this.rules[0].opcodes[30] = { type: 4, index: 12 };// RNM(issued-at) + this.rules[0].opcodes[31] = { type: 3, min: 0, max: 1 };// REP + this.rules[0].opcodes[32] = { type: 2, children: [33,34,35] };// CAT + this.rules[0].opcodes[33] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[34] = { type: 4, index: 1 };// RNM(ex-title) + this.rules[0].opcodes[35] = { type: 4, index: 13 };// RNM(expiration-time) + this.rules[0].opcodes[36] = { type: 3, min: 0, max: 1 };// REP + this.rules[0].opcodes[37] = { type: 2, children: [38,39,40] };// CAT + this.rules[0].opcodes[38] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[39] = { type: 4, index: 2 };// RNM(nb-title) + this.rules[0].opcodes[40] = { type: 4, index: 14 };// RNM(not-before) + this.rules[0].opcodes[41] = { type: 3, min: 0, max: 1 };// REP + this.rules[0].opcodes[42] = { type: 2, children: [43,44,45] };// CAT + this.rules[0].opcodes[43] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[44] = { type: 4, index: 3 };// RNM(ri-title) + this.rules[0].opcodes[45] = { type: 4, index: 15 };// RNM(request-id) + this.rules[0].opcodes[46] = { type: 3, min: 0, max: 1 };// REP + this.rules[0].opcodes[47] = { type: 2, children: [48,49,50] };// CAT + this.rules[0].opcodes[48] = { type: 4, index: 78 };// RNM(LF) + this.rules[0].opcodes[49] = { type: 4, index: 4 };// RNM(re-title) + this.rules[0].opcodes[50] = { type: 4, index: 17 };// RNM(resources) + + /* ex-title */ + this.rules[1].opcodes = []; + this.rules[1].opcodes[0] = { type: 6, string: [69,120,112,105,114,97,116,105,111,110,32,84,105,109,101,58,32] };// TBS + + /* nb-title */ + this.rules[2].opcodes = []; + this.rules[2].opcodes[0] = { type: 6, string: [78,111,116,32,66,101,102,111,114,101,58,32] };// TBS + + /* ri-title */ + this.rules[3].opcodes = []; + this.rules[3].opcodes[0] = { type: 6, string: [82,101,113,117,101,115,116,32,73,68,58,32] };// TBS + + /* re-title */ + this.rules[4].opcodes = []; + this.rules[4].opcodes[0] = { type: 6, string: [82,101,115,111,117,114,99,101,115,58] };// TBS + + /* oscheme */ + this.rules[5].opcodes = []; + this.rules[5].opcodes[0] = { type: 3, min: 0, max: 1 };// REP + this.rules[5].opcodes[1] = { type: 2, children: [2,3,9] };// CAT + this.rules[5].opcodes[2] = { type: 4, index: 77 };// RNM(ALPHA) + this.rules[5].opcodes[3] = { type: 3, min: 0, max: Infinity };// REP + this.rules[5].opcodes[4] = { type: 1, children: [5,6,7,8] };// ALT + this.rules[5].opcodes[5] = { type: 4, index: 77 };// RNM(ALPHA) + this.rules[5].opcodes[6] = { type: 4, index: 79 };// RNM(DIGIT) + this.rules[5].opcodes[7] = { type: 6, string: [43] };// TBS + this.rules[5].opcodes[8] = { type: 5, min: 45, max: 46 };// TRG + this.rules[5].opcodes[9] = { type: 7, string: [58,47,47] };// TLS + + /* domain */ + this.rules[6].opcodes = []; + this.rules[6].opcodes[0] = { type: 4, index: 52 };// RNM(authority-d) + + /* address */ + this.rules[7].opcodes = []; + this.rules[7].opcodes[0] = { type: 2, children: [1,2] };// CAT + this.rules[7].opcodes[1] = { type: 7, string: [48,120] };// TLS + this.rules[7].opcodes[2] = { type: 3, min: 40, max: 40 };// REP + this.rules[7].opcodes[3] = { type: 4, index: 80 };// RNM(HEXDIG) + + /* statement */ + this.rules[8].opcodes = []; + this.rules[8].opcodes[0] = { type: 3, min: 1, max: Infinity };// REP + this.rules[8].opcodes[1] = { type: 1, children: [2,3,4,5,6,7,8,9,10,11,12,13] };// ALT + this.rules[8].opcodes[2] = { type: 5, min: 97, max: 122 };// TRG + this.rules[8].opcodes[3] = { type: 5, min: 65, max: 90 };// TRG + this.rules[8].opcodes[4] = { type: 5, min: 48, max: 57 };// TRG + this.rules[8].opcodes[5] = { type: 5, min: 32, max: 33 };// TRG + this.rules[8].opcodes[6] = { type: 5, min: 35, max: 36 };// TRG + this.rules[8].opcodes[7] = { type: 5, min: 38, max: 59 };// TRG + this.rules[8].opcodes[8] = { type: 6, string: [61] };// TBS + this.rules[8].opcodes[9] = { type: 5, min: 63, max: 64 };// TRG + this.rules[8].opcodes[10] = { type: 6, string: [91] };// TBS + this.rules[8].opcodes[11] = { type: 6, string: [93] };// TBS + this.rules[8].opcodes[12] = { type: 6, string: [95] };// TBS + this.rules[8].opcodes[13] = { type: 6, string: [126] };// TBS + + /* empty-statement */ + this.rules[9].opcodes = []; + this.rules[9].opcodes[0] = { type: 2, children: [1,2,3] };// CAT + this.rules[9].opcodes[1] = { type: 4, index: 78 };// RNM(LF) + this.rules[9].opcodes[2] = { type: 4, index: 78 };// RNM(LF) + this.rules[9].opcodes[3] = { type: 4, index: 78 };// RNM(LF) + + /* version */ + this.rules[10].opcodes = []; + this.rules[10].opcodes[0] = { type: 7, string: [49] };// TLS + + /* nonce */ + this.rules[11].opcodes = []; + this.rules[11].opcodes[0] = { type: 3, min: 8, max: Infinity };// REP + this.rules[11].opcodes[1] = { type: 1, children: [2,3] };// ALT + this.rules[11].opcodes[2] = { type: 4, index: 77 };// RNM(ALPHA) + this.rules[11].opcodes[3] = { type: 4, index: 79 };// RNM(DIGIT) + + /* issued-at */ + this.rules[12].opcodes = []; + this.rules[12].opcodes[0] = { type: 4, index: 76 };// RNM(date-time) + + /* expiration-time */ + this.rules[13].opcodes = []; + this.rules[13].opcodes[0] = { type: 4, index: 76 };// RNM(date-time) + + /* not-before */ + this.rules[14].opcodes = []; + this.rules[14].opcodes[0] = { type: 4, index: 76 };// RNM(date-time) + + /* request-id */ + this.rules[15].opcodes = []; + this.rules[15].opcodes[0] = { type: 3, min: 0, max: Infinity };// REP + this.rules[15].opcodes[1] = { type: 4, index: 62 };// RNM(pchar) + + /* chain-id */ + this.rules[16].opcodes = []; + this.rules[16].opcodes[0] = { type: 3, min: 1, max: Infinity };// REP + this.rules[16].opcodes[1] = { type: 4, index: 79 };// RNM(DIGIT) + + /* resources */ + this.rules[17].opcodes = []; + this.rules[17].opcodes[0] = { type: 3, min: 0, max: Infinity };// REP + this.rules[17].opcodes[1] = { type: 2, children: [2,3] };// CAT + this.rules[17].opcodes[2] = { type: 4, index: 78 };// RNM(LF) + this.rules[17].opcodes[3] = { type: 4, index: 18 };// RNM(resource) + + /* resource */ + this.rules[18].opcodes = []; + this.rules[18].opcodes[0] = { type: 2, children: [1,2] };// CAT + this.rules[18].opcodes[1] = { type: 7, string: [45,32] };// TLS + this.rules[18].opcodes[2] = { type: 4, index: 47 };// RNM(URI-r) + + /* URI */ + this.rules[19].opcodes = []; + this.rules[19].opcodes[0] = { type: 2, children: [1,2,3,4,8] };// CAT + this.rules[19].opcodes[1] = { type: 4, index: 21 };// RNM(scheme) + this.rules[19].opcodes[2] = { type: 7, string: [58] };// TLS + this.rules[19].opcodes[3] = { type: 4, index: 20 };// RNM(hier-part) + this.rules[19].opcodes[4] = { type: 3, min: 0, max: 1 };// REP + this.rules[19].opcodes[5] = { type: 2, children: [6,7] };// CAT + this.rules[19].opcodes[6] = { type: 7, string: [63] };// TLS + this.rules[19].opcodes[7] = { type: 4, index: 45 };// RNM(query) + this.rules[19].opcodes[8] = { type: 3, min: 0, max: 1 };// REP + this.rules[19].opcodes[9] = { type: 2, children: [10,11] };// CAT + this.rules[19].opcodes[10] = { type: 7, string: [35] };// TLS + this.rules[19].opcodes[11] = { type: 4, index: 46 };// RNM(fragment) + + /* hier-part */ + this.rules[20].opcodes = []; + this.rules[20].opcodes[0] = { type: 1, children: [1,5,6,7] };// ALT + this.rules[20].opcodes[1] = { type: 2, children: [2,3,4] };// CAT + this.rules[20].opcodes[2] = { type: 7, string: [47,47] };// TLS + this.rules[20].opcodes[3] = { type: 4, index: 22 };// RNM(authority) + this.rules[20].opcodes[4] = { type: 4, index: 23 };// RNM(path-abempty) + this.rules[20].opcodes[5] = { type: 4, index: 24 };// RNM(path-absolute) + this.rules[20].opcodes[6] = { type: 4, index: 25 };// RNM(path-rootless) + this.rules[20].opcodes[7] = { type: 4, index: 26 };// RNM(path-empty) + + /* scheme */ + this.rules[21].opcodes = []; + this.rules[21].opcodes[0] = { type: 2, children: [1,2] };// CAT + this.rules[21].opcodes[1] = { type: 4, index: 77 };// RNM(ALPHA) + this.rules[21].opcodes[2] = { type: 3, min: 0, max: Infinity };// REP + this.rules[21].opcodes[3] = { type: 1, children: [4,5,6,7] };// ALT + this.rules[21].opcodes[4] = { type: 4, index: 77 };// RNM(ALPHA) + this.rules[21].opcodes[5] = { type: 4, index: 79 };// RNM(DIGIT) + this.rules[21].opcodes[6] = { type: 6, string: [43] };// TBS + this.rules[21].opcodes[7] = { type: 5, min: 45, max: 46 };// TRG + + /* authority */ + this.rules[22].opcodes = []; + this.rules[22].opcodes[0] = { type: 2, children: [1,3,4] };// CAT + this.rules[22].opcodes[1] = { type: 3, min: 0, max: 1 };// REP + this.rules[22].opcodes[2] = { type: 4, index: 27 };// RNM(userinfo-at) + this.rules[22].opcodes[3] = { type: 4, index: 29 };// RNM(host) + this.rules[22].opcodes[4] = { type: 3, min: 0, max: 1 };// REP + this.rules[22].opcodes[5] = { type: 2, children: [6,7] };// CAT + this.rules[22].opcodes[6] = { type: 7, string: [58] };// TLS + this.rules[22].opcodes[7] = { type: 4, index: 44 };// RNM(port) + + /* path-abempty */ + this.rules[23].opcodes = []; + this.rules[23].opcodes[0] = { type: 3, min: 0, max: Infinity };// REP + this.rules[23].opcodes[1] = { type: 2, children: [2,3] };// CAT + this.rules[23].opcodes[2] = { type: 7, string: [47] };// TLS + this.rules[23].opcodes[3] = { type: 4, index: 60 };// RNM(segment) + + /* path-absolute */ + this.rules[24].opcodes = []; + this.rules[24].opcodes[0] = { type: 2, children: [1,2] };// CAT + this.rules[24].opcodes[1] = { type: 7, string: [47] };// TLS + this.rules[24].opcodes[2] = { type: 3, min: 0, max: 1 };// REP + this.rules[24].opcodes[3] = { type: 2, children: [4,5] };// CAT + this.rules[24].opcodes[4] = { type: 4, index: 61 };// RNM(segment-nz) + this.rules[24].opcodes[5] = { type: 3, min: 0, max: Infinity };// REP + this.rules[24].opcodes[6] = { type: 2, children: [7,8] };// CAT + this.rules[24].opcodes[7] = { type: 7, string: [47] };// TLS + this.rules[24].opcodes[8] = { type: 4, index: 60 };// RNM(segment) + + /* path-rootless */ + this.rules[25].opcodes = []; + this.rules[25].opcodes[0] = { type: 2, children: [1,2] };// CAT + this.rules[25].opcodes[1] = { type: 4, index: 61 };// RNM(segment-nz) + this.rules[25].opcodes[2] = { type: 3, min: 0, max: Infinity };// REP + this.rules[25].opcodes[3] = { type: 2, children: [4,5] };// CAT + this.rules[25].opcodes[4] = { type: 7, string: [47] };// TLS + this.rules[25].opcodes[5] = { type: 4, index: 60 };// RNM(segment) + + /* path-empty */ + this.rules[26].opcodes = []; + this.rules[26].opcodes[0] = { type: 7, string: [] };// TLS + + /* userinfo-at */ + this.rules[27].opcodes = []; + this.rules[27].opcodes[0] = { type: 2, children: [1,2] };// CAT + this.rules[27].opcodes[1] = { type: 4, index: 28 };// RNM(userinfo) + this.rules[27].opcodes[2] = { type: 6, string: [64] };// TBS + + /* userinfo */ + this.rules[28].opcodes = []; + this.rules[28].opcodes[0] = { type: 3, min: 0, max: Infinity };// REP + this.rules[28].opcodes[1] = { type: 1, children: [2,3,4,5,6,7,8,9,10,11,12] };// ALT + this.rules[28].opcodes[2] = { type: 5, min: 97, max: 122 };// TRG + this.rules[28].opcodes[3] = { type: 5, min: 65, max: 90 };// TRG + this.rules[28].opcodes[4] = { type: 5, min: 48, max: 57 };// TRG + this.rules[28].opcodes[5] = { type: 4, index: 63 };// RNM(pct-encoded) + this.rules[28].opcodes[6] = { type: 6, string: [33] };// TBS + this.rules[28].opcodes[7] = { type: 6, string: [36] };// TBS + this.rules[28].opcodes[8] = { type: 5, min: 38, max: 46 };// TRG + this.rules[28].opcodes[9] = { type: 5, min: 58, max: 59 };// TRG + this.rules[28].opcodes[10] = { type: 6, string: [61] };// TBS + this.rules[28].opcodes[11] = { type: 6, string: [95] };// TBS + this.rules[28].opcodes[12] = { type: 6, string: [126] };// TBS + + /* host */ + this.rules[29].opcodes = []; + this.rules[29].opcodes[0] = { type: 1, children: [1,2,6] };// ALT + this.rules[29].opcodes[1] = { type: 4, index: 30 };// RNM(IP-literal) + this.rules[29].opcodes[2] = { type: 2, children: [3,4] };// CAT + this.rules[29].opcodes[3] = { type: 4, index: 39 };// RNM(IPv4address) + this.rules[29].opcodes[4] = { type: 13 };// NOT + this.rules[29].opcodes[5] = { type: 4, index: 43 };// RNM(reg-name-char) + this.rules[29].opcodes[6] = { type: 4, index: 42 };// RNM(reg-name) + + /* IP-literal */ + this.rules[30].opcodes = []; + this.rules[30].opcodes[0] = { type: 2, children: [1,2,5] };// CAT + this.rules[30].opcodes[1] = { type: 7, string: [91] };// TLS + this.rules[30].opcodes[2] = { type: 1, children: [3,4] };// ALT + this.rules[30].opcodes[3] = { type: 4, index: 32 };// RNM(IPv6address) + this.rules[30].opcodes[4] = { type: 4, index: 31 };// RNM(IPvFuture) + this.rules[30].opcodes[5] = { type: 7, string: [93] };// TLS + + /* IPvFuture */ + this.rules[31].opcodes = []; + this.rules[31].opcodes[0] = { type: 2, children: [1,2,4,5] };// CAT + this.rules[31].opcodes[1] = { type: 7, string: [118] };// TLS + this.rules[31].opcodes[2] = { type: 3, min: 1, max: Infinity };// REP + this.rules[31].opcodes[3] = { type: 4, index: 80 };// RNM(HEXDIG) + this.rules[31].opcodes[4] = { type: 7, string: [46] };// TLS + this.rules[31].opcodes[5] = { type: 3, min: 1, max: Infinity };// REP + this.rules[31].opcodes[6] = { type: 1, children: [7,8,9,10,11,12,13,14,15,16] };// ALT + this.rules[31].opcodes[7] = { type: 5, min: 97, max: 122 };// TRG + this.rules[31].opcodes[8] = { type: 5, min: 65, max: 90 };// TRG + this.rules[31].opcodes[9] = { type: 5, min: 48, max: 57 };// TRG + this.rules[31].opcodes[10] = { type: 6, string: [33] };// TBS + this.rules[31].opcodes[11] = { type: 6, string: [36] };// TBS + this.rules[31].opcodes[12] = { type: 5, min: 38, max: 46 };// TRG + this.rules[31].opcodes[13] = { type: 5, min: 58, max: 59 };// TRG + this.rules[31].opcodes[14] = { type: 6, string: [61] };// TBS + this.rules[31].opcodes[15] = { type: 6, string: [95] };// TBS + this.rules[31].opcodes[16] = { type: 6, string: [126] };// TBS + + /* IPv6address */ + this.rules[32].opcodes = []; + this.rules[32].opcodes[0] = { type: 1, children: [1,2] };// ALT + this.rules[32].opcodes[1] = { type: 4, index: 33 };// RNM(nodcolon) + this.rules[32].opcodes[2] = { type: 4, index: 34 };// RNM(dcolon) + + /* nodcolon */ + this.rules[33].opcodes = []; + this.rules[33].opcodes[0] = { type: 2, children: [1,5] };// CAT + this.rules[33].opcodes[1] = { type: 2, children: [2,3] };// CAT + this.rules[33].opcodes[2] = { type: 4, index: 37 };// RNM(h16n) + this.rules[33].opcodes[3] = { type: 3, min: 0, max: Infinity };// REP + this.rules[33].opcodes[4] = { type: 4, index: 38 };// RNM(h16cn) + this.rules[33].opcodes[5] = { type: 3, min: 0, max: 1 };// REP + this.rules[33].opcodes[6] = { type: 2, children: [7,8] };// CAT + this.rules[33].opcodes[7] = { type: 6, string: [58] };// TBS + this.rules[33].opcodes[8] = { type: 4, index: 39 };// RNM(IPv4address) + + /* dcolon */ + this.rules[34].opcodes = []; + this.rules[34].opcodes[0] = { type: 2, children: [1,6,7] };// CAT + this.rules[34].opcodes[1] = { type: 3, min: 0, max: 1 };// REP + this.rules[34].opcodes[2] = { type: 2, children: [3,4] };// CAT + this.rules[34].opcodes[3] = { type: 4, index: 35 };// RNM(h16) + this.rules[34].opcodes[4] = { type: 3, min: 0, max: Infinity };// REP + this.rules[34].opcodes[5] = { type: 4, index: 36 };// RNM(h16c) + this.rules[34].opcodes[6] = { type: 6, string: [58,58] };// TBS + this.rules[34].opcodes[7] = { type: 1, children: [8,17] };// ALT + this.rules[34].opcodes[8] = { type: 2, children: [9,13] };// CAT + this.rules[34].opcodes[9] = { type: 2, children: [10,11] };// CAT + this.rules[34].opcodes[10] = { type: 4, index: 37 };// RNM(h16n) + this.rules[34].opcodes[11] = { type: 3, min: 0, max: Infinity };// REP + this.rules[34].opcodes[12] = { type: 4, index: 38 };// RNM(h16cn) + this.rules[34].opcodes[13] = { type: 3, min: 0, max: 1 };// REP + this.rules[34].opcodes[14] = { type: 2, children: [15,16] };// CAT + this.rules[34].opcodes[15] = { type: 6, string: [58] };// TBS + this.rules[34].opcodes[16] = { type: 4, index: 39 };// RNM(IPv4address) + this.rules[34].opcodes[17] = { type: 3, min: 0, max: 1 };// REP + this.rules[34].opcodes[18] = { type: 4, index: 39 };// RNM(IPv4address) + + /* h16 */ + this.rules[35].opcodes = []; + this.rules[35].opcodes[0] = { type: 3, min: 1, max: 4 };// REP + this.rules[35].opcodes[1] = { type: 4, index: 80 };// RNM(HEXDIG) + + /* h16c */ + this.rules[36].opcodes = []; + this.rules[36].opcodes[0] = { type: 2, children: [1,2] };// CAT + this.rules[36].opcodes[1] = { type: 6, string: [58] };// TBS + this.rules[36].opcodes[2] = { type: 3, min: 1, max: 4 };// REP + this.rules[36].opcodes[3] = { type: 4, index: 80 };// RNM(HEXDIG) + + /* h16n */ + this.rules[37].opcodes = []; + this.rules[37].opcodes[0] = { type: 2, children: [1,3] };// CAT + this.rules[37].opcodes[1] = { type: 3, min: 1, max: 4 };// REP + this.rules[37].opcodes[2] = { type: 4, index: 80 };// RNM(HEXDIG) + this.rules[37].opcodes[3] = { type: 13 };// NOT + this.rules[37].opcodes[4] = { type: 6, string: [46] };// TBS + + /* h16cn */ + this.rules[38].opcodes = []; + this.rules[38].opcodes[0] = { type: 2, children: [1,2,4] };// CAT + this.rules[38].opcodes[1] = { type: 6, string: [58] };// TBS + this.rules[38].opcodes[2] = { type: 3, min: 1, max: 4 };// REP + this.rules[38].opcodes[3] = { type: 4, index: 80 };// RNM(HEXDIG) + this.rules[38].opcodes[4] = { type: 13 };// NOT + this.rules[38].opcodes[5] = { type: 6, string: [46] };// TBS + + /* IPv4address */ + this.rules[39].opcodes = []; + this.rules[39].opcodes[0] = { type: 2, children: [1,2,3,4,5,6,7] };// CAT + this.rules[39].opcodes[1] = { type: 4, index: 40 };// RNM(dec-octet) + this.rules[39].opcodes[2] = { type: 7, string: [46] };// TLS + this.rules[39].opcodes[3] = { type: 4, index: 40 };// RNM(dec-octet) + this.rules[39].opcodes[4] = { type: 7, string: [46] };// TLS + this.rules[39].opcodes[5] = { type: 4, index: 40 };// RNM(dec-octet) + this.rules[39].opcodes[6] = { type: 7, string: [46] };// TLS + this.rules[39].opcodes[7] = { type: 4, index: 40 };// RNM(dec-octet) + + /* dec-octet */ + this.rules[40].opcodes = []; + this.rules[40].opcodes[0] = { type: 3, min: 0, max: 3 };// REP + this.rules[40].opcodes[1] = { type: 4, index: 41 };// RNM(dec-digit) + + /* dec-digit */ + this.rules[41].opcodes = []; + this.rules[41].opcodes[0] = { type: 5, min: 48, max: 57 };// TRG + + /* reg-name */ + this.rules[42].opcodes = []; + this.rules[42].opcodes[0] = { type: 3, min: 0, max: Infinity };// REP + this.rules[42].opcodes[1] = { type: 4, index: 43 };// RNM(reg-name-char) + + /* reg-name-char */ + this.rules[43].opcodes = []; + this.rules[43].opcodes[0] = { type: 1, children: [1,2,3,4,5,6,7,8,9,10,11] };// ALT + this.rules[43].opcodes[1] = { type: 5, min: 97, max: 122 };// TRG + this.rules[43].opcodes[2] = { type: 5, min: 65, max: 90 };// TRG + this.rules[43].opcodes[3] = { type: 5, min: 48, max: 57 };// TRG + this.rules[43].opcodes[4] = { type: 4, index: 63 };// RNM(pct-encoded) + this.rules[43].opcodes[5] = { type: 6, string: [33] };// TBS + this.rules[43].opcodes[6] = { type: 6, string: [36] };// TBS + this.rules[43].opcodes[7] = { type: 5, min: 38, max: 46 };// TRG + this.rules[43].opcodes[8] = { type: 6, string: [59] };// TBS + this.rules[43].opcodes[9] = { type: 6, string: [61] };// TBS + this.rules[43].opcodes[10] = { type: 6, string: [95] };// TBS + this.rules[43].opcodes[11] = { type: 6, string: [126] };// TBS + + /* port */ + this.rules[44].opcodes = []; + this.rules[44].opcodes[0] = { type: 3, min: 0, max: Infinity };// REP + this.rules[44].opcodes[1] = { type: 4, index: 79 };// RNM(DIGIT) + + /* query */ + this.rules[45].opcodes = []; + this.rules[45].opcodes[0] = { type: 3, min: 0, max: Infinity };// REP + this.rules[45].opcodes[1] = { type: 1, children: [2,3,4] };// ALT + this.rules[45].opcodes[2] = { type: 4, index: 62 };// RNM(pchar) + this.rules[45].opcodes[3] = { type: 6, string: [47] };// TBS + this.rules[45].opcodes[4] = { type: 6, string: [63] };// TBS + + /* fragment */ + this.rules[46].opcodes = []; + this.rules[46].opcodes[0] = { type: 3, min: 0, max: Infinity };// REP + this.rules[46].opcodes[1] = { type: 1, children: [2,3,4] };// ALT + this.rules[46].opcodes[2] = { type: 4, index: 62 };// RNM(pchar) + this.rules[46].opcodes[3] = { type: 6, string: [47] };// TBS + this.rules[46].opcodes[4] = { type: 6, string: [63] };// TBS + + /* URI-r */ + this.rules[47].opcodes = []; + this.rules[47].opcodes[0] = { type: 2, children: [1,2,3,4,8] };// CAT + this.rules[47].opcodes[1] = { type: 4, index: 49 };// RNM(scheme-r) + this.rules[47].opcodes[2] = { type: 7, string: [58] };// TLS + this.rules[47].opcodes[3] = { type: 4, index: 48 };// RNM(hier-part-r) + this.rules[47].opcodes[4] = { type: 3, min: 0, max: 1 };// REP + this.rules[47].opcodes[5] = { type: 2, children: [6,7] };// CAT + this.rules[47].opcodes[6] = { type: 7, string: [63] };// TLS + this.rules[47].opcodes[7] = { type: 4, index: 50 };// RNM(query-r) + this.rules[47].opcodes[8] = { type: 3, min: 0, max: 1 };// REP + this.rules[47].opcodes[9] = { type: 2, children: [10,11] };// CAT + this.rules[47].opcodes[10] = { type: 7, string: [35] };// TLS + this.rules[47].opcodes[11] = { type: 4, index: 51 };// RNM(fragment-r) + + /* hier-part-r */ + this.rules[48].opcodes = []; + this.rules[48].opcodes[0] = { type: 1, children: [1,5,6,7] };// ALT + this.rules[48].opcodes[1] = { type: 2, children: [2,3,4] };// CAT + this.rules[48].opcodes[2] = { type: 7, string: [47,47] };// TLS + this.rules[48].opcodes[3] = { type: 4, index: 52 };// RNM(authority-d) + this.rules[48].opcodes[4] = { type: 4, index: 56 };// RNM(path-abempty-r) + this.rules[48].opcodes[5] = { type: 4, index: 57 };// RNM(path-absolute-r) + this.rules[48].opcodes[6] = { type: 4, index: 58 };// RNM(path-rootless-r) + this.rules[48].opcodes[7] = { type: 4, index: 59 };// RNM(path-empty-r) + + /* scheme-r */ + this.rules[49].opcodes = []; + this.rules[49].opcodes[0] = { type: 2, children: [1,2] };// CAT + this.rules[49].opcodes[1] = { type: 4, index: 77 };// RNM(ALPHA) + this.rules[49].opcodes[2] = { type: 3, min: 0, max: Infinity };// REP + this.rules[49].opcodes[3] = { type: 1, children: [4,5,6,7] };// ALT + this.rules[49].opcodes[4] = { type: 4, index: 77 };// RNM(ALPHA) + this.rules[49].opcodes[5] = { type: 4, index: 79 };// RNM(DIGIT) + this.rules[49].opcodes[6] = { type: 6, string: [43] };// TBS + this.rules[49].opcodes[7] = { type: 5, min: 45, max: 46 };// TRG + + /* query-r */ + this.rules[50].opcodes = []; + this.rules[50].opcodes[0] = { type: 3, min: 0, max: Infinity };// REP + this.rules[50].opcodes[1] = { type: 1, children: [2,3,4] };// ALT + this.rules[50].opcodes[2] = { type: 4, index: 62 };// RNM(pchar) + this.rules[50].opcodes[3] = { type: 6, string: [47] };// TBS + this.rules[50].opcodes[4] = { type: 6, string: [63] };// TBS + + /* fragment-r */ + this.rules[51].opcodes = []; + this.rules[51].opcodes[0] = { type: 3, min: 0, max: Infinity };// REP + this.rules[51].opcodes[1] = { type: 1, children: [2,3,4] };// ALT + this.rules[51].opcodes[2] = { type: 4, index: 62 };// RNM(pchar) + this.rules[51].opcodes[3] = { type: 6, string: [47] };// TBS + this.rules[51].opcodes[4] = { type: 6, string: [63] };// TBS + + /* authority-d */ + this.rules[52].opcodes = []; + this.rules[52].opcodes[0] = { type: 2, children: [1,5,6] };// CAT + this.rules[52].opcodes[1] = { type: 3, min: 0, max: 1 };// REP + this.rules[52].opcodes[2] = { type: 2, children: [3,4] };// CAT + this.rules[52].opcodes[3] = { type: 4, index: 53 };// RNM(userinfo-d) + this.rules[52].opcodes[4] = { type: 6, string: [64] };// TBS + this.rules[52].opcodes[5] = { type: 4, index: 54 };// RNM(host-d) + this.rules[52].opcodes[6] = { type: 3, min: 0, max: 1 };// REP + this.rules[52].opcodes[7] = { type: 2, children: [8,9] };// CAT + this.rules[52].opcodes[8] = { type: 7, string: [58] };// TLS + this.rules[52].opcodes[9] = { type: 4, index: 55 };// RNM(port-d) + + /* userinfo-d */ + this.rules[53].opcodes = []; + this.rules[53].opcodes[0] = { type: 3, min: 0, max: Infinity };// REP + this.rules[53].opcodes[1] = { type: 1, children: [2,3,4,5,6,7,8,9,10,11,12] };// ALT + this.rules[53].opcodes[2] = { type: 5, min: 97, max: 122 };// TRG + this.rules[53].opcodes[3] = { type: 5, min: 65, max: 90 };// TRG + this.rules[53].opcodes[4] = { type: 5, min: 48, max: 57 };// TRG + this.rules[53].opcodes[5] = { type: 4, index: 63 };// RNM(pct-encoded) + this.rules[53].opcodes[6] = { type: 6, string: [33] };// TBS + this.rules[53].opcodes[7] = { type: 6, string: [36] };// TBS + this.rules[53].opcodes[8] = { type: 5, min: 38, max: 46 };// TRG + this.rules[53].opcodes[9] = { type: 5, min: 58, max: 59 };// TRG + this.rules[53].opcodes[10] = { type: 6, string: [61] };// TBS + this.rules[53].opcodes[11] = { type: 6, string: [95] };// TBS + this.rules[53].opcodes[12] = { type: 6, string: [126] };// TBS + + /* host-d */ + this.rules[54].opcodes = []; + this.rules[54].opcodes[0] = { type: 1, children: [1,2,6] };// ALT + this.rules[54].opcodes[1] = { type: 4, index: 30 };// RNM(IP-literal) + this.rules[54].opcodes[2] = { type: 2, children: [3,4] };// CAT + this.rules[54].opcodes[3] = { type: 4, index: 39 };// RNM(IPv4address) + this.rules[54].opcodes[4] = { type: 13 };// NOT + this.rules[54].opcodes[5] = { type: 4, index: 43 };// RNM(reg-name-char) + this.rules[54].opcodes[6] = { type: 4, index: 42 };// RNM(reg-name) + + /* port-d */ + this.rules[55].opcodes = []; + this.rules[55].opcodes[0] = { type: 3, min: 0, max: Infinity };// REP + this.rules[55].opcodes[1] = { type: 4, index: 79 };// RNM(DIGIT) + + /* path-abempty-r */ + this.rules[56].opcodes = []; + this.rules[56].opcodes[0] = { type: 3, min: 0, max: Infinity };// REP + this.rules[56].opcodes[1] = { type: 2, children: [2,3] };// CAT + this.rules[56].opcodes[2] = { type: 7, string: [47] };// TLS + this.rules[56].opcodes[3] = { type: 4, index: 60 };// RNM(segment) + + /* path-absolute-r */ + this.rules[57].opcodes = []; + this.rules[57].opcodes[0] = { type: 2, children: [1,2] };// CAT + this.rules[57].opcodes[1] = { type: 7, string: [47] };// TLS + this.rules[57].opcodes[2] = { type: 3, min: 0, max: 1 };// REP + this.rules[57].opcodes[3] = { type: 2, children: [4,5] };// CAT + this.rules[57].opcodes[4] = { type: 4, index: 61 };// RNM(segment-nz) + this.rules[57].opcodes[5] = { type: 3, min: 0, max: Infinity };// REP + this.rules[57].opcodes[6] = { type: 2, children: [7,8] };// CAT + this.rules[57].opcodes[7] = { type: 7, string: [47] };// TLS + this.rules[57].opcodes[8] = { type: 4, index: 60 };// RNM(segment) + + /* path-rootless-r */ + this.rules[58].opcodes = []; + this.rules[58].opcodes[0] = { type: 2, children: [1,2] };// CAT + this.rules[58].opcodes[1] = { type: 4, index: 61 };// RNM(segment-nz) + this.rules[58].opcodes[2] = { type: 3, min: 0, max: Infinity };// REP + this.rules[58].opcodes[3] = { type: 2, children: [4,5] };// CAT + this.rules[58].opcodes[4] = { type: 7, string: [47] };// TLS + this.rules[58].opcodes[5] = { type: 4, index: 60 };// RNM(segment) + + /* path-empty-r */ + this.rules[59].opcodes = []; + this.rules[59].opcodes[0] = { type: 7, string: [] };// TLS + + /* segment */ + this.rules[60].opcodes = []; + this.rules[60].opcodes[0] = { type: 3, min: 0, max: Infinity };// REP + this.rules[60].opcodes[1] = { type: 4, index: 62 };// RNM(pchar) + + /* segment-nz */ + this.rules[61].opcodes = []; + this.rules[61].opcodes[0] = { type: 3, min: 1, max: Infinity };// REP + this.rules[61].opcodes[1] = { type: 4, index: 62 };// RNM(pchar) + + /* pchar */ + this.rules[62].opcodes = []; + this.rules[62].opcodes[0] = { type: 1, children: [1,2,3,4,5,6,7,8,9,10,11,12] };// ALT + this.rules[62].opcodes[1] = { type: 5, min: 97, max: 122 };// TRG + this.rules[62].opcodes[2] = { type: 5, min: 65, max: 90 };// TRG + this.rules[62].opcodes[3] = { type: 5, min: 48, max: 57 };// TRG + this.rules[62].opcodes[4] = { type: 4, index: 63 };// RNM(pct-encoded) + this.rules[62].opcodes[5] = { type: 6, string: [33] };// TBS + this.rules[62].opcodes[6] = { type: 6, string: [36] };// TBS + this.rules[62].opcodes[7] = { type: 5, min: 38, max: 46 };// TRG + this.rules[62].opcodes[8] = { type: 5, min: 58, max: 59 };// TRG + this.rules[62].opcodes[9] = { type: 6, string: [61] };// TBS + this.rules[62].opcodes[10] = { type: 6, string: [64] };// TBS + this.rules[62].opcodes[11] = { type: 6, string: [95] };// TBS + this.rules[62].opcodes[12] = { type: 6, string: [126] };// TBS + + /* pct-encoded */ + this.rules[63].opcodes = []; + this.rules[63].opcodes[0] = { type: 2, children: [1,2,3] };// CAT + this.rules[63].opcodes[1] = { type: 6, string: [37] };// TBS + this.rules[63].opcodes[2] = { type: 4, index: 80 };// RNM(HEXDIG) + this.rules[63].opcodes[3] = { type: 4, index: 80 };// RNM(HEXDIG) + + /* date-fullyear */ + this.rules[64].opcodes = []; + this.rules[64].opcodes[0] = { type: 3, min: 4, max: 4 };// REP + this.rules[64].opcodes[1] = { type: 4, index: 79 };// RNM(DIGIT) + + /* date-month */ + this.rules[65].opcodes = []; + this.rules[65].opcodes[0] = { type: 3, min: 2, max: 2 };// REP + this.rules[65].opcodes[1] = { type: 4, index: 79 };// RNM(DIGIT) + + /* date-mday */ + this.rules[66].opcodes = []; + this.rules[66].opcodes[0] = { type: 3, min: 2, max: 2 };// REP + this.rules[66].opcodes[1] = { type: 4, index: 79 };// RNM(DIGIT) + + /* time-hour */ + this.rules[67].opcodes = []; + this.rules[67].opcodes[0] = { type: 3, min: 2, max: 2 };// REP + this.rules[67].opcodes[1] = { type: 4, index: 79 };// RNM(DIGIT) + + /* time-minute */ + this.rules[68].opcodes = []; + this.rules[68].opcodes[0] = { type: 3, min: 2, max: 2 };// REP + this.rules[68].opcodes[1] = { type: 4, index: 79 };// RNM(DIGIT) + + /* time-second */ + this.rules[69].opcodes = []; + this.rules[69].opcodes[0] = { type: 3, min: 2, max: 2 };// REP + this.rules[69].opcodes[1] = { type: 4, index: 79 };// RNM(DIGIT) + + /* time-secfrac */ + this.rules[70].opcodes = []; + this.rules[70].opcodes[0] = { type: 2, children: [1,2] };// CAT + this.rules[70].opcodes[1] = { type: 7, string: [46] };// TLS + this.rules[70].opcodes[2] = { type: 3, min: 1, max: Infinity };// REP + this.rules[70].opcodes[3] = { type: 4, index: 79 };// RNM(DIGIT) + + /* time-numoffset */ + this.rules[71].opcodes = []; + this.rules[71].opcodes[0] = { type: 2, children: [1,4,5,6] };// CAT + this.rules[71].opcodes[1] = { type: 1, children: [2,3] };// ALT + this.rules[71].opcodes[2] = { type: 7, string: [43] };// TLS + this.rules[71].opcodes[3] = { type: 7, string: [45] };// TLS + this.rules[71].opcodes[4] = { type: 4, index: 67 };// RNM(time-hour) + this.rules[71].opcodes[5] = { type: 7, string: [58] };// TLS + this.rules[71].opcodes[6] = { type: 4, index: 68 };// RNM(time-minute) + + /* time-offset */ + this.rules[72].opcodes = []; + this.rules[72].opcodes[0] = { type: 1, children: [1,2] };// ALT + this.rules[72].opcodes[1] = { type: 7, string: [122] };// TLS + this.rules[72].opcodes[2] = { type: 4, index: 71 };// RNM(time-numoffset) + + /* partial-time */ + this.rules[73].opcodes = []; + this.rules[73].opcodes[0] = { type: 2, children: [1,2,3,4,5,6] };// CAT + this.rules[73].opcodes[1] = { type: 4, index: 67 };// RNM(time-hour) + this.rules[73].opcodes[2] = { type: 7, string: [58] };// TLS + this.rules[73].opcodes[3] = { type: 4, index: 68 };// RNM(time-minute) + this.rules[73].opcodes[4] = { type: 7, string: [58] };// TLS + this.rules[73].opcodes[5] = { type: 4, index: 69 };// RNM(time-second) + this.rules[73].opcodes[6] = { type: 3, min: 0, max: 1 };// REP + this.rules[73].opcodes[7] = { type: 4, index: 70 };// RNM(time-secfrac) + + /* full-date */ + this.rules[74].opcodes = []; + this.rules[74].opcodes[0] = { type: 2, children: [1,2,3,4,5] };// CAT + this.rules[74].opcodes[1] = { type: 4, index: 64 };// RNM(date-fullyear) + this.rules[74].opcodes[2] = { type: 7, string: [45] };// TLS + this.rules[74].opcodes[3] = { type: 4, index: 65 };// RNM(date-month) + this.rules[74].opcodes[4] = { type: 7, string: [45] };// TLS + this.rules[74].opcodes[5] = { type: 4, index: 66 };// RNM(date-mday) + + /* full-time */ + this.rules[75].opcodes = []; + this.rules[75].opcodes[0] = { type: 2, children: [1,2] };// CAT + this.rules[75].opcodes[1] = { type: 4, index: 73 };// RNM(partial-time) + this.rules[75].opcodes[2] = { type: 4, index: 72 };// RNM(time-offset) + + /* date-time */ + this.rules[76].opcodes = []; + this.rules[76].opcodes[0] = { type: 2, children: [1,2,3] };// CAT + this.rules[76].opcodes[1] = { type: 4, index: 74 };// RNM(full-date) + this.rules[76].opcodes[2] = { type: 7, string: [116] };// TLS + this.rules[76].opcodes[3] = { type: 4, index: 75 };// RNM(full-time) + + /* ALPHA */ + this.rules[77].opcodes = []; + this.rules[77].opcodes[0] = { type: 1, children: [1,2] };// ALT + this.rules[77].opcodes[1] = { type: 5, min: 65, max: 90 };// TRG + this.rules[77].opcodes[2] = { type: 5, min: 97, max: 122 };// TRG + + /* LF */ + this.rules[78].opcodes = []; + this.rules[78].opcodes[0] = { type: 6, string: [10] };// TBS + + /* DIGIT */ + this.rules[79].opcodes = []; + this.rules[79].opcodes[0] = { type: 5, min: 48, max: 57 };// TRG + + /* HEXDIG */ + this.rules[80].opcodes = []; + this.rules[80].opcodes[0] = { type: 1, children: [1,2,3] };// ALT + this.rules[80].opcodes[1] = { type: 5, min: 48, max: 57 };// TRG + this.rules[80].opcodes[2] = { type: 5, min: 65, max: 70 };// TRG + this.rules[80].opcodes[3] = { type: 5, min: 97, max: 102 };// TRG + + // The `toString()` function will display the original grammar file(s) that produced these opcodes. + this.toString = function toString(){ + let str = ""; + str += "; LDT 05/06/2024 \n"; + str += "; modified in several significant ways\n"; + str += "; 1) Literal strings are replaced with numbers and ranges (%d32 & %d32-126, etc.) when possible.\n"; + str += "; TRB and especially TRG operators are much more efficient than TLS operators.\n"; + str += "; 2) Two rules, authority and URI, are used multiple times in different contexts. These rules will be reproduced and renamed\n"; + str += "; in order to a) recognize the context and b) remove unneccary callback functions for certain contexts.\n"; + str += "; This will simiplify recognizing contexts AND remove unneccesary callbacks\n"; + str += "; 2.a) domain is defined as authority-d which is identical to authority except that there will be no\n"; + str += "; callback functions defined on authority-d or any of its *-d components.\n"; + str += "; 2.b) The resource URI is defined as URI-r and its components defined as *-r.\n"; + str += "; In this way, callback functions can be defined on URI and is components while\n"; + str += "; leaving URI-r to be parsed identically with no unnecessary callback functions to slow it down.\n"; + str += "; 3) IPv6address does not work because of APG's \"first-success disambiguation\" and \"greedy\" repetitions.\n"; + str += "; IPv6address redefined and validations moved to callback functions (semantic vs syntactic validation)\n"; + str += "; Redefinition requires negative look-ahead operators, https://en.wikipedia.org/wiki/Syntactic_predicate\n"; + str += "; That is SABNF instead of simple ABNF.\n"; + str += "; 4) IPv4address fails because of \"first-success disambiguation\".\n"; + str += "; This could be fixed with rearrangement of the alternative terms. However, it would still not\n"; + str += "; accept zero-padded (leading zeros) decimal octets.\n"; + str += "; Therefore, IPv4address is also done with callback functions and semantic validation.\n"; + str += "; 5) The negative look-ahead operator is also needed in the definition of host to\n"; + str += "; prevent failure with a reg-name that begins with an IPv4 address.\n"; + str += "; 6) NOTE: host = 1.1.1.256 is a valid host name even though it is an invalid IPv4address.\n"; + str += "; The IPv4address alternative fails but the reg-name alternative succeeds.\n"; + str += "; 7) The Ethereum spec (https://eips.ethereum.org/EIPS/eip-4361) message format ABNF\n"; + str += "; allows for empty statements. Because of the \"first success disambiguation\" of APG\n"; + str += "; the an explicit \"empty-statement\" rule is required to match the spec's intent.\n"; + str += "\n"; + str += "\n"; + str += "sign-in-with-ethereum =\n"; + str += " oscheme domain %s\" wants you to sign in with your Ethereum account:\" LF\n"; + str += " address LF\n"; + str += " ((LF statement LF LF) / empty-statement / (LF LF))\n"; + str += " %s\"URI: \" URI LF\n"; + str += " %s\"Version: \" version LF\n"; + str += " %s\"Chain ID: \" chain-id LF\n"; + str += " %s\"Nonce: \" nonce LF\n"; + str += " %s\"Issued At: \" issued-at\n"; + str += " [ LF ex-title expiration-time ]\n"; + str += " [ LF nb-title not-before ]\n"; + str += " [ LF ri-title request-id ]\n"; + str += " [ LF re-title resources ]\n"; + str += "ex-title = %s\"Expiration Time: \"\n"; + str += "nb-title = %s\"Not Before: \"\n"; + str += "ri-title = %s\"Request ID: \"\n"; + str += "re-title = %s\"Resources:\"\n"; + str += "oscheme = [ ALPHA *( ALPHA / DIGIT / %d43 / %d45-46 ) \"://\" ]\n"; + str += "domain = authority-d\n"; + str += "address = \"0x\" 40*40HEXDIG\n"; + str += " ; Must also conform to captilization\n"; + str += " ; checksum encoding specified in EIP-55\n"; + str += " ; where applicable (EOAs).\n"; + str += "\n"; + str += "statement = 1*( %d97-122 / %d65-90 / %d48-57 / %d32-33 / %d35-36 / %d38-59 / %d61 / %d63-64 / %d91 / %d93 / %d95 / %d126)\n"; + str += " ; The purpose is to exclude LF (line breaks).\n"; + str += " ; LDT 10/04/2023: Do you mean %d32-126? All printing characters\n"; + str += "empty-statement = LF LF LF\n"; + str += "version = \"1\"\n"; + str += "nonce = 8*( ALPHA / DIGIT )\n"; + str += "issued-at = date-time\n"; + str += "expiration-time = date-time\n"; + str += "not-before = date-time\n"; + str += "request-id = *pchar\n"; + str += "chain-id = 1*DIGIT\n"; + str += " ; See EIP-155 for valid CHAIN_IDs.\n"; + str += "resources = *( LF resource )\n"; + str += "resource = \"- \" URI-r\n"; + str += "\n"; + str += "; ------------------------------------------------------------------------------\n"; + str += "; RFC 3986\n"; + str += "\n"; + str += "URI = scheme \":\" hier-part [ \"?\" query ] [ \"#\" fragment ]\n"; + str += "hier-part = \"//\" authority path-abempty\n"; + str += " / path-absolute\n"; + str += " / path-rootless\n"; + str += " / path-empty\n"; + str += "scheme = ALPHA *( ALPHA / DIGIT / %d43 / %d45-46 )\n"; + str += "authority = [ userinfo-at ] host [ \":\" port ]\n"; + str += "path-abempty = *( \"/\" segment )\n"; + str += "path-absolute = \"/\" [ segment-nz *( \"/\" segment ) ]\n"; + str += "path-rootless = segment-nz *( \"/\" segment )\n"; + str += "path-empty = \"\"\n"; + str += "userinfo-at = userinfo %d64\n"; + str += " ; userinfo redefined to include the \"@\" so that it will fail without it\n"; + str += " ; otherwise userinfo can match host and then the parser will backtrack\n"; + str += " ; incorrectly keeping the captured userinfo phrase\n"; + str += "userinfo = *(%d97-122 / %d65-90 / %d48-57 / pct-encoded / %d33 / %d36 / %d38-46 / %d58-59 / %d61 / %d95 / %d126)\n"; + str += "host = IP-literal / (IPv4address !reg-name-char) / reg-name\n"; + str += " ; negative look-ahead required to prevent IPv4address from being recognized as first part of reg-name\n"; + str += " ; same fix as https://github.com/garycourt/uri-js/issues/4\n"; + str += "IP-literal = \"[\" ( IPv6address / IPvFuture ) \"]\"\n"; + str += "IPvFuture = \"v\" 1*HEXDIG \".\" 1*( %d97-122 / %d65-90 / %d48-57 / %d33 / %d36 /%d38-46 / %d58-59 /%d61 /%d95 / %d126 )\n"; + str += "IPv6address = nodcolon / dcolon\n"; + str += "nodcolon = (h16n *h16cn) [%d58 IPv4address]\n"; + str += "dcolon = [h16 *h16c] %d58.58 (((h16n *h16cn) [%d58 IPv4address]) / [IPv4address])\n"; + str += "h16 = 1*4HEXDIG\n"; + str += "h16c = %d58 1*4HEXDIG\n"; + str += "h16n = 1*4HEXDIG !%d46\n"; + str += "h16cn = %d58 1*4HEXDIG !%d46\n"; + str += "IPv4address = dec-octet \".\" dec-octet \".\" dec-octet \".\" dec-octet\n"; + str += "; Here we will will use callback functions to evaluate and validate the (possibly zero-padded) dec-octet.\n"; + str += "dec-octet = *3dec-digit\n"; + str += "dec-digit = %d48-57\n"; + str += "reg-name = *reg-name-char\n"; + str += "reg-name-char = %d97-122 / %d65-90 / %d48-57 / pct-encoded / %d33 / %d36 / %d38-46 / %d59 / %d61 /%d95 / %d126\n"; + str += "port = *DIGIT\n"; + str += "query = *(pchar / %d47 / %d63)\n"; + str += "fragment = *(pchar / %d47 / %d63)\n"; + str += "\n"; + str += "; URI-r is a redefiniton of URI but without the callback functions attached to it\n"; + str += "; it reuses athority-d from domain \n"; + str += "URI-r = scheme-r \":\" hier-part-r [ \"?\" query-r ] [ \"#\" fragment-r ]\n"; + str += "hier-part-r = \"//\" authority-d path-abempty-r\n"; + str += " / path-absolute-r\n"; + str += " / path-rootless-r\n"; + str += " / path-empty-r\n"; + str += "scheme-r = ALPHA *( ALPHA / DIGIT / %d43 / %d45-46 )\n"; + str += "query-r = *(pchar / %d47 / %d63)\n"; + str += "fragment-r = *(pchar / %d47 / %d63)\n"; + str += "\n"; + str += "; authority-d is a redefinition of authority for capturing the domian phrase\n"; + str += "; but without callback functions \n"; + str += "; it is reused for URI- for the same reason \n"; + str += "authority-d = [ userinfo-d %d64 ] host-d [ \":\" port-d ]\n"; + str += "userinfo-d = *(%d97-122 / %d65-90 / %d48-57 / pct-encoded / %d33 / %d36 / %d38-46 / %d58-59 / %d61 / %d95 / %d126)\n"; + str += "host-d = IP-literal / (IPv4address !reg-name-char) / reg-name\n"; + str += "port-d = *DIGIT\n"; + str += "\n"; + str += "; for use with URI-r\n"; + str += "path-abempty-r = *( \"/\" segment )\n"; + str += "path-absolute-r = \"/\" [ segment-nz *( \"/\" segment ) ]\n"; + str += "path-rootless-r = segment-nz *( \"/\" segment )\n"; + str += "path-empty-r = \"\"\n"; + str += "segment = *pchar\n"; + str += "segment-nz = 1*pchar\n"; + str += "pchar = (%d97-122 / %d65-90 / %d48-57 / pct-encoded / %d33 / %d36 / %d38-46 /%d58-59 / %d61 / %d64 / %d95 / %d126)\n"; + str += "pct-encoded = %d37 HEXDIG HEXDIG\n"; + str += "\n"; + str += "; no longer needed - expanded for all usage for fewer branches in the parse there\n"; + str += "; and more efficient use of the TBS & TRG operators in place of TLS and rule names\n"; + str += "; does not work with APG probably because of \"first-success disambiguation\" and greedy repetitions.\n"; + str += "; will replace with semantic checking of valid number of h16s\n"; + str += ";IPv6address = 6( h16 \":\" ) ls32\n"; + str += "; / \"::\" 5( h16 \":\" ) ls32\n"; + str += "; / [ h16 ] \"::\" 4( h16 \":\" ) ls32\n"; + str += "; / [ *1( h16 \":\" ) h16 ] \"::\" 3( h16 \":\" ) ls32\n"; + str += "; / [ *2( h16 \":\" ) h16 ] \"::\" 2( h16 \":\" ) ls32\n"; + str += "; / [ *3( h16 \":\" ) h16 ] \"::\" h16 \":\" ls32\n"; + str += "; / [ *4( h16 \":\" ) h16 ] \"::\" ls32\n"; + str += "; / [ *5( h16 \":\" ) h16 ] \"::\" h16\n"; + str += "; / [ *6( h16 \":\" ) h16 ] \"::\"\n"; + str += ";ls32 = ( h16 \":\" h16 ) / IPv4address\n"; + str += "; dec-octet does not work because of \"first-success disambiguation\".\n"; + str += "; Must have the longest (3-digit) numbers first.\n"; + str += "; Even so, this form does not accept leading zeros.\n"; + str += "; There does not seem to be a clear standard for this (https://en.wikipedia.org/wiki/Dot-decimal_notation)\n"; + str += "; however and early RFC 790 did show leading-zero padding of the three digits.\n"; + str += ";dec-octet = DIGIT ; 0-9\n"; + str += "; / %x31-39 DIGIT ; 10-99\n"; + str += "; / \"1\" 2DIGIT ; 100-199\n"; + str += "; / \"2\" %x30-34 DIGIT ; 200-249\n"; + str += "; / \"25\" %x30-35 ; 250-255\n"; + str += ";statement = 1*( reserved / unreserved / \" \" )\n"; + str += ";scheme = ALPHA *( ALPHA / DIGIT / \"+\" / \"-\" / \".\" )\n"; + str += ";authority = [ userinfo \"@\" ] host [ \":\" port ]\n"; + str += ";userinfo = *( unreserved / pct-encoded / sub-delims / \":\" )\n"; + str += ";query = *( pchar / \"/\" / \"?\" )\n"; + str += ";fragment = *( pchar / \"/\" / \"?\" )\n"; + str += ";IPvFuture = \"v\" 1*HEXDIG \".\" 1*( unreserved / sub-delims / \":\" )\n"; + str += ";reg-name = *( unreserved / pct-encoded / sub-delims )\n"; + str += ";pct-encoded = \"%\" HEXDIG HEXDIG\n"; + str += ";pchar = unreserved / pct-encoded / sub-delims / \":\" / \"@\"\n"; + str += ";path-empty = 0pchar; deprecated - empty literal string, \"\", is more efficient \n"; + str += ";unreserved = ALPHA / DIGIT / \"-\" / \".\" / \"_\" / \"~\"\n"; + str += ";reserved = gen-delims / sub-delims\n"; + str += ";gen-delims = \":\" / \"/\" / \"?\" / \"#\" / \"[\" / \"]\" / \"@\"\n"; + str += ";sub-delims = \"!\" / \"$\" / \"&\" / \"'\" / \"(\" / \")\"\n"; + str += "; / \"*\" / \"+\" / \",\" / \";\" / \"=\"\n"; + str += ";HEXDIG = DIGIT / \"A\" / \"B\" / \"C\" / \"D\" / \"E\" / \"F\"\n"; + str += "\n"; + str += "; ------------------------------------------------------------------------------\n"; + str += "; RFC 3339\n"; + str += "\n"; + str += "date-fullyear = 4DIGIT\n"; + str += "date-month = 2DIGIT ; 01-12\n"; + str += "date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on\n"; + str += " ; month/year\n"; + str += "time-hour = 2DIGIT ; 00-23\n"; + str += "time-minute = 2DIGIT ; 00-59\n"; + str += "time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second\n"; + str += " ; rules\n"; + str += "time-secfrac = \".\" 1*DIGIT\n"; + str += "time-numoffset = (\"+\" / \"-\") time-hour \":\" time-minute\n"; + str += "time-offset = \"Z\" / time-numoffset\n"; + str += "\n"; + str += "partial-time = time-hour \":\" time-minute \":\" time-second\n"; + str += " [time-secfrac]\n"; + str += "full-date = date-fullyear \"-\" date-month \"-\" date-mday\n"; + str += "full-time = partial-time time-offset\n"; + str += "\n"; + str += "date-time = full-date \"T\" full-time\n"; + str += "\n"; + str += "; ------------------------------------------------------------------------------\n"; + str += "; RFC 5234\n"; + str += "\n"; + str += "ALPHA = %x41-5A / %x61-7A ; A-Z / a-z\n"; + str += "LF = %x0A\n"; + str += " ; linefeed\n"; + str += "DIGIT = %x30-39\n"; + str += " ; 0-9\n"; + str += "HEXDIG = %d48-57 / %d65-70 / %d97-102\n"; + str += "\n"; + return str; + } +} diff --git a/packages/siwe-parser/lib/unit.test.ts b/packages/siwe-parser/lib/unit.test.ts new file mode 100644 index 00000000..c03a8078 --- /dev/null +++ b/packages/siwe-parser/lib/unit.test.ts @@ -0,0 +1,116 @@ +import { ParsedMessage } from "./abnf"; +import apgLib from "apg-js/src/apg-lib/node-exports"; +import { grammar } from "./siwe-grammar"; +import * as fs from "fs"; + +const validChars: object = JSON.parse( + fs.readFileSync("../../test/valid_chars.json", "utf-8") +); +const invalidChars: object = JSON.parse( + fs.readFileSync("../../test/invalid_chars.json", "utf-8") +); +const validUris: object = JSON.parse( + fs.readFileSync("../../test/valid_uris.json", "utf-8") +); +const invalidUris: object = JSON.parse( + fs.readFileSync("../../test/invalid_uris.json", "utf-8") +); +const validResources: object = JSON.parse( + fs.readFileSync("../../test/valid_resources.json", "utf-8") +); +const invalidResources: object = JSON.parse( + fs.readFileSync("../../test/invalid_resources.json", "utf-8") +); +const validSpec: object = JSON.parse( + fs.readFileSync("../../test/valid_specification.json", "utf-8") +); + +const grammarObj = new grammar(); +const apgParser = new apgLib.parser(); +let result; + +/* + The ABNF in the siwe message format and RFC3986 have a number of rules + for primitive strings that are processed many times during the parsing of a message. + apg-js processes the terminal nodes the strings are defined by much more + efficiently than the rule names themselves. + The terminal nodes are processed most efficiently in the order + TRG(%d65-90) > TBS(%d65.66.67) > TLS("some string") > rule + Therefore, in siwe-abnf.txt these strings have been expanded into terminal nodes. + The "valid character" and "invalid character" tests check that these + expansions have been done correctly. +*/ +describe("Valid character tests - rules with characters expanded to primitives.", () => { + test.concurrent.each(Object.entries(validChars))( + "Rule: %s", + (test_name, test) => { + result = apgParser.parse(grammarObj, test.rule, test.input); + expect(result.success).toBe(test.answer); + } + ); +}); +describe("Invalid character tests - rules with characters expanded to primitives.", () => { + test.concurrent.each(Object.entries(invalidChars))( + "Rule + invalid character: %s", + (test_name, test) => { + result = apgParser.parse(grammarObj, test.rule, test.input); + expect(result.success).toBe(test.answer); + } + ); +}); +describe("Valid URIs", () => { + test.concurrent.each(Object.entries(validUris))("%s", (test_name, test) => { + const parsedMessage = new ParsedMessage(test.msg); + for (const [field, value] of Object.entries(test.uri)) { + if (value === null) { + expect(parsedMessage.uriElements[field]).toBeUndefined(); + } else { + expect(parsedMessage.uriElements[field]).toBe(value); + } + } + }); +}); +describe("Invalid URIs", () => { + test.concurrent.each(Object.entries(invalidUris))("%s", (test_name, test) => { + expect(() => new ParsedMessage(test)).toThrow(); + }); +}); +describe("Valid Resource URIs", () => { + test.concurrent.each(Object.entries(validResources))( + "%s", + (test_name, test) => { + const parsedMessage = new ParsedMessage(test.msg); + for (let i = 0; i < test.resources.length; i += 1) { + expect(parsedMessage.resources[i]).toBe(test.resources[i]); + } + } + ); +}); +describe("Invalid resources URI", () => { + test.concurrent.each(Object.entries(invalidResources))( + "%s", + (test_name, test) => { + expect(() => new ParsedMessage(test)).toThrow(); + } + ); +}); +/* + A close look at the siwe message format reveals that "statement", + "request-id" and "resources" may be present, empty or missing entirely. + These tests verify that the siwe-parser matches the specification on + these points. +*/ +describe("Statement, request-id & resources may be present, empty or missing.", () => { + test.concurrent.each(Object.entries(validSpec))("%s", (test_name, test) => { + const parsedMessage = new ParsedMessage(test.msg); + for (const [field, value] of Object.entries(test.items)) { + if (value === null) { + expect(parsedMessage[field]).toBeUndefined(); + } else if (typeof value === "object") { + expect(parsedMessage[field]).toStrictEqual(value); + } else { + expect(parsedMessage[field]).toBe(value); + } + } + }); +}); diff --git a/packages/siwe-parser/lib/utils.ts b/packages/siwe-parser/lib/utils.ts index 05c24f47..4965b6f7 100644 --- a/packages/siwe-parser/lib/utils.ts +++ b/packages/siwe-parser/lib/utils.ts @@ -1,32 +1,32 @@ -import { keccak_256 } from '@noble/hashes/sha3'; -import { bytesToHex } from '@noble/hashes/utils'; +import { keccak_256 } from "@noble/hashes/sha3"; +import { bytesToHex } from "@noble/hashes/utils"; /** * This method is supposed to check if an address is conforming to EIP-55. * @param address Address to be checked if conforms with EIP-55. * @returns Either the return is or not in the EIP-55 format. */ export const isEIP55Address = (address: string) => { - if (address.length != 42) { - return false; - } + if (address.length != 42) { + return false; + } - const lowerAddress = `${address}`.toLowerCase().replace('0x', ''); - const hash = bytesToHex(keccak_256(lowerAddress)); - let ret = '0x'; + const lowerAddress = `${address}`.toLowerCase().replace("0x", ""); + const hash = bytesToHex(keccak_256(lowerAddress)); + let ret = "0x"; - for (let i = 0; i < lowerAddress.length; i++) { - if (parseInt(hash[i], 16) >= 8) { - ret += lowerAddress[i].toUpperCase(); - } else { - ret += lowerAddress[i]; - } + for (let i = 0; i < lowerAddress.length; i++) { + if (parseInt(hash[i], 16) >= 8) { + ret += lowerAddress[i].toUpperCase(); + } else { + ret += lowerAddress[i]; } - return address === ret; -} + } + return address === ret; +}; export const parseIntegerNumber = (number: string): number => { - const parsed = parseInt(number); - if (isNaN(parsed)) throw new Error("Invalid number."); - if (parsed === Infinity) throw new Error("Invalid number."); - return parsed; -} + const parsed = parseInt(number); + if (isNaN(parsed)) throw new Error("Invalid number."); + if (parsed === Infinity) throw new Error("Invalid number."); + return parsed; +}; diff --git a/packages/siwe-parser/package.json b/packages/siwe-parser/package.json index 2444e1ca..df70752e 100644 --- a/packages/siwe-parser/package.json +++ b/packages/siwe-parser/package.json @@ -1,6 +1,6 @@ { "name": "@spruceid/siwe-parser", - "version": "2.1.2", + "version": "3.0.0", "description": "Parse Messages that conform to EIP-4361: Sign-In with Ethereum (SIWE)", "main": "dist/parsers.js", "types": "dist/parsers.d.ts", @@ -11,7 +11,8 @@ "test": "jest", "build": "tsc", "lint": "eslint --ext .js,.ts .", - "format": "prettier --ignore-path .gitignore --write \"**/*.+(js|ts|json)\"" + "format": "prettier --ignore-path .gitignore --write \"**/*.+(js|ts|json)\"", + "apg": "../../node_modules/apg-js/bin/apg.sh -i ./lib/siwe-abnf.txt -o ./lib/siwe-grammar --typescript" }, "author": "Spruce Systems Inc.", "keywords": [ @@ -25,9 +26,7 @@ "license": "Apache-2.0", "dependencies": { "@noble/hashes": "^1.1.2", - "apg-js": "^4.3.0", - "uri-js": "^4.4.1", - "valid-url": "^1.0.9" + "apg-js": "^4.4.0" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^5.23.0", diff --git a/packages/siwe-parser/tsconfig.json b/packages/siwe-parser/tsconfig.json index 4fb8c138..bb185e12 100644 --- a/packages/siwe-parser/tsconfig.json +++ b/packages/siwe-parser/tsconfig.json @@ -1,12 +1,10 @@ { "compilerOptions": { "module": "commonjs", - "target": "es2015", + "target": "ES2018", "declaration": true, "outDir": "./dist", "esModuleInterop": true }, - "include": [ - "lib/*" - ] + "include": ["lib/*"] } diff --git a/packages/siwe/lib/client.test.ts b/packages/siwe/lib/client.test.ts index 4e30e063..8d2acaef 100644 --- a/packages/siwe/lib/client.test.ts +++ b/packages/siwe/lib/client.test.ts @@ -1,11 +1,23 @@ -import * as fs from "fs"; +import * as fs from 'fs'; -const parsingPositive: object = JSON.parse(fs.readFileSync('../../test/parsing_positive.json', 'utf8')); -const parsingNegative: object = JSON.parse(fs.readFileSync('../../test/parsing_negative.json', 'utf8')); -const parsingNegativeObjects: object = JSON.parse(fs.readFileSync('../../test/parsing_negative_objects.json', 'utf8')); -const verificationPositive: object = JSON.parse(fs.readFileSync('../../test/verification_positive.json', 'utf8')); -const verificationNegative: object = JSON.parse(fs.readFileSync('../../test/verification_negative.json', 'utf8')); -const EIP1271: object = JSON.parse(fs.readFileSync('../../test/eip1271.json', 'utf8')); +const parsingPositive: object = JSON.parse( + fs.readFileSync('../../test/parsing_positive.json', 'utf8') +); +const parsingNegative: object = JSON.parse( + fs.readFileSync('../../test/parsing_negative.json', 'utf8') +); +const parsingNegativeObjects: object = JSON.parse( + fs.readFileSync('../../test/parsing_negative_objects.json', 'utf8') +); +const verificationPositive: object = JSON.parse( + fs.readFileSync('../../test/verification_positive.json', 'utf8') +); +const verificationNegative: object = JSON.parse( + fs.readFileSync('../../test/verification_negative.json', 'utf8') +); +const EIP1271: object = JSON.parse( + fs.readFileSync('../../test/eip1271.json', 'utf8') +); import { // @ts-expect-error -- ethers v6 compatibility hack @@ -30,8 +42,9 @@ describe(`Message Generation`, () => { (n, test) => { try { new SiweMessage(test); + expect(false).toBeTruthy(); } catch (error) { - expect(Object.values(SiweErrorType).includes(error)); + expect(true).toBeTruthy(); } } ); @@ -41,8 +54,9 @@ describe(`Message Generation`, () => { (n, test) => { try { new SiweMessage(test as any); + expect(false).toBeTruthy(); } catch (error) { - expect(Object.values(SiweErrorType).includes(error)); + expect(true).toBeTruthy(); } } ); @@ -62,15 +76,7 @@ describe(`Message verification without suppressExceptions`, () => { domain: (test_fields as any).domainBinding, nonce: (test_fields as any).matchNonce, }) - // when validate is removed uncomment this and remove the following then - // .then(({ success }) => success) - .then(async ({ data }) => { - jest - .useFakeTimers() - .setSystemTime(new Date((test_fields as any).time || test_fields.issuedAt)); - const res = await msg.validate(test_fields.signature); - return res === data; - }) + .then(({ success }) => success) ).resolves.toBeTruthy(); jest.useRealTimers(); diff --git a/packages/siwe/lib/client.ts b/packages/siwe/lib/client.ts index bf3b9fac..823dfda4 100644 --- a/packages/siwe/lib/client.ts +++ b/packages/siwe/lib/client.ts @@ -1,12 +1,7 @@ // TODO: Figure out how to get types from this lib: -import { - isEIP55Address, - ParsedMessage, - parseIntegerNumber, -} from '@spruceid/siwe-parser'; -import * as uri from 'valid-url'; +import { ParsedMessage, parseIntegerNumber } from '@spruceid/siwe-parser'; -import { getAddress, Provider, verifyMessage } from './ethersCompat'; +import { Provider, verifyMessage } from './ethersCompat'; import { SiweError, SiweErrorType, @@ -20,7 +15,6 @@ import { checkContractWalletSignature, generateNonce, checkInvalidKeys, - isValidISO8601Date, } from './utils'; export class SiweMessage { @@ -69,6 +63,7 @@ export class SiweMessage { */ constructor(param: string | Partial) { if (typeof param === 'string') { + /* the message string (including nonce) is valid or ParsedMessage will throw */ const parsedMessage = new ParsedMessage(param); this.scheme = parsedMessage.scheme; this.domain = parsedMessage.domain; @@ -100,24 +95,27 @@ export class SiweMessage { if (typeof this.chainId === 'string') { this.chainId = parseIntegerNumber(this.chainId); } + this.nonce = this.nonce || generateNonce(); + /* the message object is valid or parsing its stringified value will throw */ + new ParsedMessage(this.prepareMessage()); } - this.nonce = this.nonce || generateNonce(); - this.validateMessage(); } /** - * This function can be used to retrieve an EIP-4361 formated message for + * This function can be used to retrieve an EIP-4361 formatted message for * signature, although you can call it directly it's advised to use * [prepareMessage()] instead which will resolve to the correct method based * on the [type] attribute of this object, in case of other formats being * implemented. - * @returns {string} EIP-4361 formated message, ready for EIP-191 signing. + * @returns {string} EIP-4361 formatted message, ready for EIP-191 signing. */ toMessage(): string { /** Validates all fields of the object */ - this.validateMessage(); - const headerPrefx = this.scheme ? `${this.scheme}://${this.domain}` : this.domain; - const header = `${headerPrefx} wants you to sign in with your Ethereum account:`; + // this.validateMessage(); + const headerPrefix = this.scheme + ? `${this.scheme}://${this.domain}` + : this.domain; + const header = `${headerPrefix} wants you to sign in with your Ethereum account:`; const uriField = `URI: ${this.uri}`; let prefix = [header, this.address].join('\n'); const versionField = `Version: ${this.version}`; @@ -158,7 +156,7 @@ export class SiweMessage { const suffix = suffixArray.join('\n'); prefix = [prefix, this.statement].join('\n\n'); - if (this.statement) { + if (this.statement !== undefined) { prefix += '\n'; } return [prefix, suffix].join('\n'); @@ -186,23 +184,6 @@ export class SiweMessage { return message; } - /** - * @deprecated - * Verifies the integrity of the object by matching its signature. - * @param signature Signature to match the address in the message. - * @param provider Ethers provider to be used for EIP-1271 validation - */ - async validate(signature: string, provider?: Provider) { - console.warn( - 'validate() has been deprecated, please update your code to use verify(). validate() may be removed in future versions.' - ); - return this.verify({ signature }, { provider, suppressExceptions: false }) - .then(({ data }) => data) - .catch(({ error }) => { - throw error; - }); - } - /** * Verifies the integrity of the object by matching its signature. * @param params Parameters to verify the integrity of the message, signature is required. @@ -239,7 +220,7 @@ export class SiweMessage { opts, VerifyOptsKeys ); - if (invalidParams.length > 0) { + if (invalidOpts.length > 0) { fail({ success: false, data: this, @@ -399,87 +380,4 @@ export class SiweMessage { } }); } - - /** - * Validates the values of this object fields. - * @throws Throws an {ErrorType} if a field is invalid. - */ - private validateMessage(...args) { - /** Checks if the user might be using the function to verify instead of validate. */ - if (args.length > 0) { - throw new SiweError( - SiweErrorType.UNABLE_TO_PARSE, - `Unexpected argument in the validateMessage function.` - ); - } - - /** `domain` check. */ - if ( - !this.domain || - this.domain.length === 0 || - !/[^#?]*/.test(this.domain) - ) { - throw new SiweError( - SiweErrorType.INVALID_DOMAIN, - `${this.domain} to be a valid domain.` - ); - } - - /** EIP-55 `address` check. */ - if (!isEIP55Address(this.address)) { - throw new SiweError( - SiweErrorType.INVALID_ADDRESS, - getAddress(this.address), - this.address - ); - } - - /** Check if the URI is valid. */ - if (!uri.isUri(this.uri)) { - throw new SiweError( - SiweErrorType.INVALID_URI, - `${this.uri} to be a valid uri.` - ); - } - - /** Check if the version is 1. */ - if (this.version !== '1') { - throw new SiweError( - SiweErrorType.INVALID_MESSAGE_VERSION, - '1', - this.version - ); - } - - /** Check if the nonce is alphanumeric and bigger then 8 characters */ - const nonce = this?.nonce?.match(/[a-zA-Z0-9]{8,}/); - if (!nonce || this.nonce.length < 8 || nonce[0] !== this.nonce) { - throw new SiweError( - SiweErrorType.INVALID_NONCE, - `Length > 8 (${nonce.length}). Alphanumeric.`, - this.nonce - ); - } - - /** `issuedAt` conforms to ISO-8601 and is a valid date. */ - if (this.issuedAt) { - if (!isValidISO8601Date(this.issuedAt)) { - throw new Error(SiweErrorType.INVALID_TIME_FORMAT); - } - } - - /** `expirationTime` conforms to ISO-8601 and is a valid date. */ - if (this.expirationTime) { - if (!isValidISO8601Date(this.expirationTime)) { - throw new Error(SiweErrorType.INVALID_TIME_FORMAT); - } - } - - /** `notBefore` conforms to ISO-8601 and is a valid date. */ - if (this.notBefore) { - if (!isValidISO8601Date(this.notBefore)) { - throw new Error(SiweErrorType.INVALID_TIME_FORMAT); - } - } - } } diff --git a/packages/siwe/lib/ethersCompat.ts b/packages/siwe/lib/ethersCompat.ts index 5c66c150..73c4a200 100644 --- a/packages/siwe/lib/ethersCompat.ts +++ b/packages/siwe/lib/ethersCompat.ts @@ -7,26 +7,26 @@ type Ethers6BigNumberish = string | number | bigint; type Ethers6SignatureLike = | string | { - r: string; - s: string; - v: Ethers6BigNumberish; - yParity?: 0 | 1; - yParityAndS?: string; - } + r: string; + s: string; + v: Ethers6BigNumberish; + yParity?: 0 | 1; + yParityAndS?: string; + } | { - r: string; - yParityAndS: string; - yParity?: 0 | 1; - s?: string; - v?: number; - } + r: string; + yParityAndS: string; + yParity?: 0 | 1; + s?: string; + v?: number; + } | { - r: string; - s: string; - yParity: 0 | 1; - v?: Ethers6BigNumberish; - yParityAndS?: string; - }; + r: string; + s: string; + yParity: 0 | 1; + v?: Ethers6BigNumberish; + yParityAndS?: string; + }; let ethersVerifyMessage = null; let ethersHashMessage = null; @@ -53,10 +53,10 @@ try { } // @ts-expect-error -- v6 compatibility hack -type ProviderV5 = ethers.providers.Provider -type ProviderV6 = ethers.Provider +type ProviderV5 = ethers.providers.Provider; +type ProviderV6 = ethers.Provider; -export type Provider = ProviderV6 extends undefined ? ProviderV5 : ProviderV6 +export type Provider = ProviderV6 extends undefined ? ProviderV5 : ProviderV6; export const verifyMessage = ethersVerifyMessage; export const hashMessage = ethersHashMessage; export const getAddress = ethersGetAddress; diff --git a/packages/siwe/lib/objects.test.ts b/packages/siwe/lib/objects.test.ts new file mode 100644 index 00000000..5971e506 --- /dev/null +++ b/packages/siwe/lib/objects.test.ts @@ -0,0 +1,21 @@ +import { SiweMessage } from './client'; +import * as fs from 'fs'; + +const messages: object = JSON.parse( + fs.readFileSync('../../test/message_objects.json', 'utf8') +); + +let siweMsg; +let re; +describe(`Message Generation`, () => { + test.concurrent.each(Object.entries(messages))('%s', (n, test) => { + try { + siweMsg = new SiweMessage(test.msg); + expect(siweMsg).toBeDefined(); + } catch (tryError) { + re = new RegExp(`(.|\n)*${test.error}`); + console.error(test.error); + expect(n.startsWith('invalid')).toBe(true); + } + }); +}); diff --git a/packages/siwe/lib/types.ts b/packages/siwe/lib/types.ts index df14e191..6583cee3 100644 --- a/packages/siwe/lib/types.ts +++ b/packages/siwe/lib/types.ts @@ -35,7 +35,12 @@ export interface VerifyOpts { suppressExceptions?: boolean; /** Enables a custom verification function that will be ran alongside EIP-1271 check. */ - verificationFallback?: (params: VerifyParams, opts: VerifyOpts, message: SiweMessage, EIP1271Promise: Promise) => Promise; + verificationFallback?: ( + params: VerifyParams, + opts: VerifyOpts, + message: SiweMessage, + EIP1271Promise: Promise + ) => Promise; } export const VerifyOptsKeys: Array = [ @@ -62,7 +67,11 @@ export interface SiweResponse { * Interface used to return errors in SiweResponses. */ export class SiweError { - constructor(type: SiweErrorType | string, expected?: string, received?: string) { + constructor( + type: SiweErrorType | string, + expected?: string, + received?: string + ) { this.type = type; this.expected = expected; this.received = received; @@ -112,7 +121,7 @@ export enum SiweErrorType { /** Signature doesn't match the address of the message. */ INVALID_SIGNATURE = 'Signature does not match address of the message.', - /** `expirationTime`, `notBefore` or `issuedAt` not complient to ISO-8601. */ + /** `expirationTime`, `notBefore` or `issuedAt` not compliant to ISO-8601. */ INVALID_TIME_FORMAT = 'Invalid time format.', /** `version` is not 1. */ diff --git a/packages/siwe/lib/utils.ts b/packages/siwe/lib/utils.ts index 8a5447ad..6edc70cd 100644 --- a/packages/siwe/lib/utils.ts +++ b/packages/siwe/lib/utils.ts @@ -57,14 +57,14 @@ export const generateNonce = (): string => { * This method matches the given date string against the ISO-8601 regex and also * performs checks if it's a valid date. * @param inputDate any string to be validated against ISO-8601 - * @returns boolean indicating if the providade date is valid and conformant to ISO-8601 + * @returns boolean indicating if the provided date is valid and conformant to ISO-8601 */ export const isValidISO8601Date = (inputDate: string): boolean => { /* Split groups and make sure inputDate is in ISO8601 format */ const inputMatch = ISO8601.exec(inputDate); /* if inputMatch is null the date is not ISO-8601 */ - if (!inputDate) { + if (!inputMatch) { return false; } diff --git a/packages/siwe/package.json b/packages/siwe/package.json index f2107ba4..43b0f498 100644 --- a/packages/siwe/package.json +++ b/packages/siwe/package.json @@ -1,6 +1,6 @@ { "name": "siwe", - "version": "2.3.2", + "version": "3.0.0", "description": "Sign-In with Ethereum", "main": "dist/siwe.js", "types": "dist/siwe.d.ts", @@ -23,10 +23,8 @@ ], "homepage": "https://github.com/spruceid/siwe", "dependencies": { - "@spruceid/siwe-parser": "^2.1.2", - "@stablelib/random": "^1.0.1", - "uri-js": "^4.4.1", - "valid-url": "^1.0.9" + "@spruceid/siwe-parser": "^3.0.0", + "@stablelib/random": "^1.0.1" }, "devDependencies": { "@typescript-eslint/eslint-plugin": "^5.23.0", diff --git a/packages/siwe/tsconfig.json b/packages/siwe/tsconfig.json index cd68510c..bb185e12 100644 --- a/packages/siwe/tsconfig.json +++ b/packages/siwe/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "module": "commonjs", - "target": "es2015", + "target": "ES2018", "declaration": true, "outDir": "./dist", "esModuleInterop": true diff --git a/test/invalid_chars.json b/test/invalid_chars.json new file mode 100644 index 00000000..e0a8a4e6 --- /dev/null +++ b/test/invalid_chars.json @@ -0,0 +1,202 @@ +{ + "scheme + SP": { + "rule": "scheme", + "input": " abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-.", + "answer": false + }, + "scheme + :": { + "rule": "scheme", + "input": ":", + "answer": false + }, + "scheme + #": { + "rule": "scheme", + "input": "#", + "answer": false + }, + "scheme + ?": { + "rule": "scheme", + "input": "?", + "answer": false + }, + "scheme + @": { + "rule": "scheme", + "input": "@", + "answer": false + }, + "scheme + !": { + "rule": "scheme", + "input": "!", + "answer": false + }, + "scheme + ~": { + "rule": "scheme", + "input": "~", + "answer": false + }, + "statement + `": { + "rule": "statement", + "input": "`", + "answer": false + }, + "statement + <": { + "rule": "statement", + "input": "<", + "answer": false + }, + "statement + >": { + "rule": "statement", + "input": ">", + "answer": false + }, + "statement + {": { + "rule": "statement", + "input": "{", + "answer": false + }, + "statement + |": { + "rule": "statement", + "input": "|", + "answer": false + }, + "statement + }": { + "rule": "statement", + "input": "}", + "answer": false + }, + "userinfo + /": { + "rule": "userinfo", + "input": "/", + "answer": false + }, + "userinfo + #": { + "rule": "userinfo", + "input": "#", + "answer": false + }, + "userinfo + ?": { + "rule": "userinfo", + "input": "?", + "answer": false + }, + "userinfo + @": { + "rule": "userinfo", + "input": "@", + "answer": false + }, + "userinfo + [": { + "rule": "userinfo", + "input": "[", + "answer": false + }, + "userinfo + ]": { + "rule": "userinfo", + "input": "]", + "answer": false + }, + "IPvFuture + /": { + "rule": "IPvFuture", + "input": "/", + "answer": false + }, + "IPvFuture + #": { + "rule": "IPvFuture", + "input": "#", + "answer": false + }, + "IPvFuture + ?": { + "rule": "IPvFuture", + "input": "?", + "answer": false + }, + "IPvFuture + @": { + "rule": "IPvFuture", + "input": "@", + "answer": false + }, + "IPvFuture + [": { + "rule": "IPvFuture", + "input": "[", + "answer": false + }, + "IPvFuture + ]": { + "rule": "IPvFuture", + "input": "]", + "answer": false + }, + "reg-name + /": { + "rule": "reg-name", + "input": "/", + "answer": false + }, + "reg-name + #": { + "rule": "reg-name", + "input": "#", + "answer": false + }, + "reg-name + ?": { + "rule": "reg-name", + "input": "?", + "answer": false + }, + "reg-name + @": { + "rule": "reg-name", + "input": "@", + "answer": false + }, + "reg-name + [": { + "rule": "reg-name", + "input": "[", + "answer": false + }, + "reg-name + ]": { + "rule": "reg-name", + "input": "]", + "answer": false + }, + "pchar + ^": { + "rule": "segment-nz", + "input": "^", + "answer": false + }, + "pchar + `": { + "rule": "segment-nz", + "input": "`", + "answer": false + }, + "pchar + |": { + "rule": "segment-nz", + "input": "|", + "answer": false + }, + "pchar + %": { + "rule": "segment-nz", + "input": "%", + "answer": false + }, + "pchar + ?": { + "rule": "segment-nz", + "input": "?", + "answer": false + }, + "pchar + #": { + "rule": "segment-nz", + "input": "#", + "answer": false + }, + "pchar + [": { + "rule": "segment-nz", + "input": "[", + "answer": false + }, + "fragment + #": { + "rule": "fragment", + "input": "#", + "answer": false + }, + "fragment + [": { + "rule": "fragment", + "input": "[", + "answer": false + } +} diff --git a/test/invalid_resources.json b/test/invalid_resources.json new file mode 100644 index 00000000..da5820dd --- /dev/null +++ b/test/invalid_resources.json @@ -0,0 +1,18 @@ +{ +"IPv4 bad octets: - resources uri - uri://[::0.0.0.256]/p/path": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[::0.0.0.256]/p/path", +"IPv4 bad octets: - resources uri - uri://[::300.0.0.0]/p/path": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[::300.0.0.0]/p/path", +"IPv4 bad octets: - resources uri - uri://[::0.ff.0.255]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[::0.ff.0.255]", +"IPv4 bad octets: - resources uri - uri://[::0.0.256.0]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[::0.0.256.0]", +"IPv6 no :: no IPv4 too many 16-bit digits - resources uri - uri://[ffff:abcd:0:10:200:3000:f8a:1:ffff]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[ffff:abcd:0:10:200:3000:f8a:1:ffff]", +"IPv6 no :: no IPv4 too few 16-bit digits - resources uri - uri://[ffff:abcd:0:10:200:3000:f8a]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[ffff:abcd:0:10:200:3000:f8a]", +"IPv6 no :: with IPv4 too many 16-bit digits - resources uri - uri://[ffff:abcd:0:10:200:3000:ff:255.255.255.255]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[ffff:abcd:0:10:200:3000:ff:255.255.255.255]", +"IPv6 leading :: too many 16-bit digits - resources uri - uri://[::1:2:3:4:5:6:7:8]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[::1:2:3:4:5:6:7:8]", +"IPv6 leading :: with IPv4 - too many 16-bit digits - resources uri - uri://[::1:2:3:4:5:6:198.162.10.255]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[::1:2:3:4:5:6:198.162.10.255]", +"IPv6 trailing :: too many 16-bit digits - resources uri - uri://[1:2:3:4:5:6:7:8::]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[1:2:3:4:5:6:7:8::]", +"IPv6 trailing :: with IPv4 - too many 16-bit digits - resources uri - uri://[1:2:3:4:5:6::198.162.10.255]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[1:2:3:4:5:6::198.162.10.255]", +"IPv6 leading & trailing :: no IPv4 - too many 16-bit digits - resources uri - uri://[1:2:3:4:5::6:7:8]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[1:2:3:4:5::6:7:8]", +"IPv6 leading & trailing :: with IPv4 - too many 16-bit digits - resources uri - uri://[1:2:3:4:5::6:198.162.10.255]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[1:2:3:4:5::6:198.162.10.255]", +"No scheme - resources uri - ://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- ://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body", +"bad query - resources uri - uri://user:pass@example.com:123/one/two.three ?q1=a1&q2=a2#body": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://user:pass@example.com:123/one/two.three ?q1=a1&q2=a2#body", +"bad fragment - resources uri - uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2 #body": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2 #body" +} diff --git a/test/invalid_uris.json b/test/invalid_uris.json new file mode 100644 index 00000000..be56549c --- /dev/null +++ b/test/invalid_uris.json @@ -0,0 +1,18 @@ +{ +"IPv4 bad octets: - uri://[::0.0.0.256]/p/path": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::0.0.0.256]/p/path\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"IPv4 bad octets: - uri://[::300.0.0.0]/p/path": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::300.0.0.0]/p/path\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"IPv4 bad octets: - uri://[::0.ff.0.255]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::0.ff.0.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"IPv4 bad octets: - uri://[::0.0.256.0]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::0.0.256.0]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"IPv6 no :: no IPv4 too many 16-bit digits - uri://[ffff:abcd:0:10:200:3000:f8a:1:ffff]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[ffff:abcd:0:10:200:3000:f8a:1:ffff]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"IPv6 no :: no IPv4 too few 16-bit digits - uri://[ffff:abcd:0:10:200:3000:f8a]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[ffff:abcd:0:10:200:3000:f8a]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"IPv6 no :: with IPv4 too many 16-bit digits - uri://[ffff:abcd:0:10:200:3000:ff:255.255.255.255]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[ffff:abcd:0:10:200:3000:ff:255.255.255.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"IPv6 leading :: too many 16-bit digits - uri://[::1:2:3:4:5:6:7:8]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::1:2:3:4:5:6:7:8]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"IPv6 leading :: with IPv4 - too many 16-bit digits - uri://[::1:2:3:4:5:6:198.162.10.255]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::1:2:3:4:5:6:198.162.10.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"IPv6 trailing :: too many 16-bit digits - uri://[1:2:3:4:5:6:7:8::]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[1:2:3:4:5:6:7:8::]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"IPv6 trailing :: with IPv4 - too many 16-bit digits - uri://[1:2:3:4:5:6::198.162.10.255]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[1:2:3:4:5:6::198.162.10.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"IPv6 leading & trailing :: no IPv4 - too many 16-bit digits - uri://[1:2:3:4:5::6:7:8]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[1:2:3:4:5::6:7:8]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"IPv6 leading & trailing :: with IPv4 - too many 16-bit digits - uri://[1:2:3:4:5::6:198.162.10.255]": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[1:2:3:4:5::6:198.162.10.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"No scheme - ://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: ://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"bad query - uri://user:pass@example.com:123/one/two.three ?q1=a1&q2=a2#body": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://user:pass@example.com:123/one/two.three ?q1=a1&q2=a2#body\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", +"bad fragment - uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2 #body": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2 #body\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z" +} diff --git a/test/message_objects.json b/test/message_objects.json new file mode 100644 index 00000000..ca0a2867 --- /dev/null +++ b/test/message_objects.json @@ -0,0 +1,54 @@ +{ + "valid message object: missing resources": { + "msg": {"domain":"service.org","address":"0xe5A12547fe4E872D192E3eCecb76F2Ce1aeA4946","statement":"I accept the ServiceOrg Terms of Service: https://service.org/tos","uri":"https://sample.org","version":"1","chainId":1,"nonce":"12341234","issuedAt":"2022-03-17T12:45:13.610Z","expirationTime":"2023-03-17T12:45:13.610Z","notBefore":"2022-03-17T12:45:13.610Z","requestId":"some_id"}, + "error": "none" + }, + "valid message object: empty resources": { + "msg": {"domain":"service.org","address":"0xe5A12547fe4E872D192E3eCecb76F2Ce1aeA4946","statement":"I accept the ServiceOrg Terms of Service: https://service.org/tos","uri":"https://sample.org","version":"1","chainId":1,"nonce":"12341234","issuedAt":"2022-03-17T12:45:13.610Z","expirationTime":"2023-03-17T12:45:13.610Z","notBefore":"2022-03-17T12:45:13.610Z","requestId":"some_id","resources":[]}, + "error": "none" + }, + "valid message object: single resources URI": { + "msg": {"domain":"service.org","address":"0xe5A12547fe4E872D192E3eCecb76F2Ce1aeA4946","statement":"I accept the ServiceOrg Terms of Service: https://service.org/tos","uri":"https://sample.org","version":"1","chainId":1,"nonce":"12341234","issuedAt":"2022-03-17T12:45:13.610Z","expirationTime":"2023-03-17T12:45:13.610Z","notBefore":"2022-03-17T12:45:13.610Z","requestId":"some_id","resources":["ftp://mystuff.com"]}, + "error": "none" + }, + "valid message object: multiple resources URIs": { + "msg": {"domain":"service.org","address":"0xe5A12547fe4E872D192E3eCecb76F2Ce1aeA4946","statement":"I accept the ServiceOrg Terms of Service: https://service.org/tos","uri":"https://sample.org","version":"1","chainId":1,"nonce":"12341234","issuedAt":"2022-03-17T12:45:13.610Z","expirationTime":"2023-03-17T12:45:13.610Z","notBefore":"2022-03-17T12:45:13.610Z","requestId":"some_id","resources":["ftp://mystuff.com","uri:"]}, + "error": "none" + }, + "invalid message object: invalid EIP-55 address": { + "msg": {"domain":"service.org","address":"0xe5a12547fe4E872D192E3eCecb76F2Ce1aeA4946","statement":"I accept the ServiceOrg Terms of Service: https://service.org/tos","uri":"https://sample.org","version":"1","chainId":1,"nonce":"12341234","issuedAt":"2022-03-17T12:45:13.610Z","expirationTime":"2023-03-17T12:45:13.610Z","notBefore":"2022-03-17T12:45:13.610Z","requestId":"some_id"}, + "error": "invalid EIP-55 address" + }, + "invalid message object: invalid resource URI": { + "msg": {"domain":"service.org","address":"0xe5A12547fe4E872D192E3eCecb76F2Ce1aeA4946","statement":"I accept the ServiceOrg Terms of Service: https://service.org/tos","uri":"https://sample.org","version":"1","chainId":1,"nonce":"12341234","issuedAt":"2022-03-17T12:45:13.610Z","expirationTime":"2023-03-17T12:45:13.610Z","notBefore":"2022-03-17T12:45:13.610Z","requestId":"some_id","resources":["sample.org"]}, + "error": "invalid resource URI" + }, + "invalid message object: multiple resources one good one bad}": { + "msg": {"domain":"service.org","address":"0xe5A12547fe4E872D192E3eCecb76F2Ce1aeA4946","statement":"I accept the ServiceOrg Terms of Service: https://service.org/tos","uri":"https://sample.org","version":"1","chainId":1,"nonce":"12341234","issuedAt":"2022-03-17T12:45:13.610Z","expirationTime":"2023-03-17T12:45:13.610Z","notBefore":"2022-03-17T12:45:13.610Z","requestId":"some_id","resources":["https://sample.org","sample.org"]}, + "error": "invalid resource URI" + }, + "invalid issuedAt data time: invalid issued-at date time syntax": { + "msg": {"domain":"service.org","address":"0xe5A12547fe4E872D192E3eCecb76F2Ce1aeA4946","statement":"I accept the ServiceOrg Terms of Service: https://service.org/tos","uri":"https://service.org","version":"1","chainId":1,"nonce":"12341234","issuedAt":"garbage","expirationTime":"2023-03-17T12:45:13.610Z","notBefore":"2022-03-17T12:45:13.610Z","requestId":"some_id"}, + "error": "invalid issued-at date time syntax" + }, + "invalid issuedAt data time month - 2022-13-17T12:45:13.610Z: invalid issued-at date time semantics": { + "msg": {"domain":"service.org","address":"0xe5A12547fe4E872D192E3eCecb76F2Ce1aeA4946","statement":"I accept the ServiceOrg Terms of Service: https://service.org/tos","uri":"https://service.org","version":"1","chainId":1,"nonce":"12341234","issuedAt":"2022-13-17T12:45:13.610Z","expirationTime":"2023-03-17T12:45:13.610Z","notBefore":"2022-03-17T12:45:13.610Z","requestId":"some_id"}, + "error": "invalid issued-at date time semantics" + }, + "invalid expirationTime data time: invalid expiration-time date time syntax": { + "msg": {"domain":"service.org","address":"0xe5A12547fe4E872D192E3eCecb76F2Ce1aeA4946","statement":"I accept the ServiceOrg Terms of Service: https://service.org/tos","uri":"https://service.org","version":"1","chainId":1,"nonce":"12341234","issuedAt":"2022-03-17T12:45:13.610Z","expirationTime":"garbage","notBefore":"2022-03-17T12:45:13.610Z","requestId":"some_id"}, + "error": "invalid expiration-time date time syntax" + }, + "invalid expirationTime data time day - 2023-03-32T12:45:13.610Z: invalid expiration-time date time semantics": { + "msg": {"domain":"service.org","address":"0xe5A12547fe4E872D192E3eCecb76F2Ce1aeA4946","statement":"I accept the ServiceOrg Terms of Service: https://service.org/tos","uri":"https://service.org","version":"1","chainId":1,"nonce":"12341234","issuedAt":"2022-03-17T12:45:13.610Z","expirationTime":"2023-03-32T12:45:13.610Z","notBefore":"2022-03-17T12:45:13.610Z","requestId":"some_id"}, + "error": "invalid expiration-time date time semantics" + }, + "invalid notBefore data time: invalid not-before date time syntax": { + "msg": {"domain":"service.org","address":"0xe5A12547fe4E872D192E3eCecb76F2Ce1aeA4946","statement":"I accept the ServiceOrg Terms of Service: https://service.org/tos","uri":"https://service.org","version":"1","chainId":1,"nonce":"12341234","issuedAt":"2022-03-17T12:45:13.610Z","expirationTime":"2023-03-17T12:45:13.610Z","notBefore":"garbage","requestId":"some_id"}, + "error": "invalid not-before date time syntax" + }, + "invalid notBefore data time hour - 2023-03-17T25:45:13.610Z: invalid not-before date time semantics": { + "msg": {"domain":"service.org","address":"0xe5A12547fe4E872D192E3eCecb76F2Ce1aeA4946","statement":"I accept the ServiceOrg Terms of Service: https://service.org/tos","uri":"https://service.org","version":"1","chainId":1,"nonce":"12341234","issuedAt":"2022-03-17T12:45:13.610Z","expirationTime":"2023-03-17T12:45:13.610Z","notBefore":"2023-03-17T25:45:13.610Z","requestId":"some_id"}, + "error": "invalid not-before date time semantics" + } +} diff --git a/test/valid_chars.json b/test/valid_chars.json new file mode 100644 index 00000000..9e0b62c8 --- /dev/null +++ b/test/valid_chars.json @@ -0,0 +1,42 @@ +{ + "scheme": { + "rule": "scheme", + "input": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+-.", + "answer": true + }, + "statement": { + "rule": "statement", + "input": ":/?#[]@!$&'()*+,;= abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~", + "answer": true + }, + "pct-encoded": { + "rule": "pct-encoded", + "input": "%20", + "answer": true + }, + "userinfo": { + "rule": "userinfo", + "input": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:%00%ff%FF%0a%0A%20", + "answer": true + }, + "IPvFuture": { + "rule": "IPvFuture", + "input": "v123.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:", + "answer": true + }, + "reg-name": { + "rule": "reg-name", + "input": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=%00%ff%FF%0a%0A%20", + "answer": true + }, + "pchar": { + "rule": "segment-nz", + "input": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:@%00%ff%FF%0a%0A%20", + "answer": true + }, + "fragment": { + "rule": "fragment", + "input": "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~!$&'()*+,;=:@%00%ff%FF%0a%0A%20/?", + "answer": true + } +} diff --git a/test/valid_resources.json b/test/valid_resources.json new file mode 100644 index 00000000..1fc5e350 --- /dev/null +++ b/test/valid_resources.json @@ -0,0 +1,34 @@ +{ + "Resources: [uri:, uri://@]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri:\n- uri://@", + "resources": ["uri:", "uri://@"] + }, + "Resources: [uri://@:, uri://]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://@:\n- uri://", + "resources": ["uri://@:", "uri://"] + }, + "Resources: [uri://:, uri:?]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://:\n- uri:?", + "resources": ["uri://:", "uri:?"] + }, + "Resources: [uri:#, uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri:#\n- uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body", + "resources": ["uri:#", "uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body"] + }, + "Resources IPv4: [uri://10.10.10.10, uri://010.0.00.000]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://10.10.10.10\n- uri://010.0.00.000", + "resources": ["uri://10.10.10.10", "uri://010.0.00.000"] + }, + "Resources IP-literal: [uri://[2001:db8::7], uri://[::ffff:129.144.52.38]]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[2001:db8::7]\n- uri://[::ffff:129.144.52.38]", + "resources": ["uri://[2001:db8::7]", "uri://[::ffff:129.144.52.38]"] + }, + "Resources IP-literal: [uri://10.10.10.10.example.com/en/process, uri://[2606:2800:220:1:248:1893:25c8:1946]/test]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://10.10.10.10.example.com/en/process\n- uri://[2606:2800:220:1:248:1893:25c8:1946]/test", + "resources": ["uri://10.10.10.10.example.com/en/process", "uri://[2606:2800:220:1:248:1893:25c8:1946]/test"] + }, + "Resources IP-literal: [uri://[2001:db8::1]:80, uri://[2001:db8::1:ffff]:5128]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri://[2001:db8::1]:80\n- uri://[2001:db8::1:ffff]:5128", + "resources": ["uri://[2001:db8::1]:80", "uri://[2001:db8::1:ffff]:5128"] + } +} diff --git a/test/valid_specification.json b/test/valid_specification.json new file mode 100644 index 00000000..812cedfa --- /dev/null +++ b/test/valid_specification.json @@ -0,0 +1,74 @@ +{ + "resources present": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:\n- uri:", + "items": { + "statement": null, + "requestId": null, + "resources": ["uri:"] + } + }, + "resources empty": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nResources:", + "items": { + "statement": null, + "requestId": null, + "resources": [] + } + }, + "resources missing": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "items": { + "statement": null, + "requestId": null, + "resources": null + } + }, + "request-id present": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nRequest ID: request123", + "items": { + "statement": null, + "requestId": "request123", + "resources": null + } + }, + "request-id empty": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z\nRequest ID: ", + "items": { + "statement": null, + "requestId": "", + "resources": null + } + }, + "request-id missing": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "items": { + "statement": null, + "requestId": null, + "resources": null + } + }, + "statement present": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\nhave statement\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "items": { + "statement": "have statement", + "requestId": null, + "resources": null + } + }, + "statement empty": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "items": { + "statement": "", + "requestId": null, + "resources": null + } + }, + "statement missing": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "items": { + "statement": null, + "requestId": null, + "resources": null + } + } +} diff --git a/test/valid_uris.json b/test/valid_uris.json new file mode 100644 index 00000000..eda7a514 --- /dev/null +++ b/test/valid_uris.json @@ -0,0 +1,308 @@ +{ + "uri-js scheme: uri:": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": null, + "host": null, + "port": null, + "path": "", + "query": null, + "fragment": null + } + }, + "uri-js userinfo: uri://@": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://@\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": "", + "host": "", + "port": null, + "path": "", + "query": null, + "fragment": null + } + }, + "uri-js empty host: uri://@:": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://@:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": "", + "host": "", + "port": "", + "path": "", + "query": null, + "fragment": null + } + }, + "uri-js host: uri://": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": null, + "host": "", + "port": null, + "path": "", + "query": null, + "fragment": null + } + }, + "uri-js port: uri://:": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": null, + "host": "", + "port": "", + "path": "", + "query": null, + "fragment": null + } + }, + "uri-js query: uri:?": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:?\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": null, + "host": null, + "port": null, + "path": "", + "query": "", + "fragment": null + } + }, + "uri-js fragment: uri:#": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:#\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": null, + "host": null, + "port": null, + "path": "", + "query": null, + "fragment": "" + } + }, + "uri-js all: uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://user:pass@example.com:123/one/two.three?q1=a1&q2=a2#body\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": "user:pass", + "host": "example.com", + "port": 123, + "path": "/one/two.three", + "query": "q1=a1&q2=a2", + "fragment": "body" + } + }, + "uri-js IPv4address: uri://10.10.10.10": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://10.10.10.10\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": null, + "host": "10.10.10.10", + "port": null, + "path": "", + "query": null, + "fragment": null + } + }, + "uri-js IPv6address: uri://[2001:db8::7]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[2001:db8::7]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": null, + "host": "2001:db8::7", + "port": null, + "path": "", + "query": null, + "fragment": null + } + }, + "uri-js mixed IPv6address & IPv4address: uri://[::ffff:129.144.52.38]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::ffff:129.144.52.38]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": null, + "host": "::ffff:129.144.52.38", + "port": null, + "path": "", + "query": null, + "fragment": null + } + }, + "uri-js mixed IPv4address & reg-name: uri://10.10.10.10.example.com/en/process": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://10.10.10.10.example.com/en/process\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": null, + "host": "10.10.10.10.example.com", + "port": null, + "path": "/en/process", + "query": null, + "fragment": null + } + }, + "uri-js IPv6address, example from bkw: uri://[2606:2800:220:1:248:1893:25c8:1946]/test": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[2606:2800:220:1:248:1893:25c8:1946]/test\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": null, + "host": "2606:2800:220:1:248:1893:25c8:1946", + "port": null, + "path": "/test", + "query": null, + "fragment": null + } + }, + "uri-js IPv6address, example from RFC 5952: uri://[2001:db8::1]:80": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[2001:db8::1]:80\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": null, + "host": "2001:db8::1", + "port": 80, + "path": "", + "query": null, + "fragment": null + } + }, + "uri-js end test: uri:": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri:\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "scheme": "uri", + "userinfo": null, + "host": null, + "port": null, + "path": "", + "query": null, + "fragment": null + } + }, + "IPv4address: uri://[::10.10.10.10]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::10.10.10.10]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "::10.10.10.10" + } + }, + "IPv4address leading zeros: uri://[::000.000.010.001]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::000.000.010.001]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "::000.000.010.001" + } + }, + "IPv4address max value: uri://[::001.099.200.255]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::001.099.200.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "::001.099.200.255" + } + }, + "IPv6address no :: : uri://[ffff:abcd:0:10:200:3000:f8a:1]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[ffff:abcd:0:10:200:3000:f8a:1]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "ffff:abcd:0:10:200:3000:f8a:1" + } + }, + "IPv6address no :: & IPv4: uri://[ffff:abcd:0:10:200:3000:255.255.255.255]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[ffff:abcd:0:10:200:3000:255.255.255.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "ffff:abcd:0:10:200:3000:255.255.255.255" + } + }, + "IPv6address leading :: no IPv4: uri://[::]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "::" + } + }, + "IPv6address leading :: no IPv4: uri://[::ffff]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::ffff]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "::ffff" + } + }, + "IPv6address leading :: no IPv4: uri://[::1:2:3:4:5:6:7]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::1:2:3:4:5:6:7]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "::1:2:3:4:5:6:7" + } + }, + "IPv6address leading :: with IPv4: uri://[::198.162.10.255]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::198.162.10.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "::198.162.10.255" + } + }, + "IPv6address leading :: with IPv4: uri://[::ffff:198.162.10.255]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::ffff:198.162.10.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "::ffff:198.162.10.255" + } + }, + "IPv6address leading :: with IPv4: uri://[::1:2:3:4:5:198.162.10.255]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[::1:2:3:4:5:198.162.10.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "::1:2:3:4:5:198.162.10.255" + } + }, + "IPv6address trailing :: no IPv4: uri://[1::]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[1::]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "1::" + } + }, + "IPv6address trailing :: no IPv4: uri://[1:2:3:4:5:6:7::]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[1:2:3:4:5:6:7::]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "1:2:3:4:5:6:7::" + } + }, + "IPv6address trailing :: with IPv4: uri://[1::198.162.10.255]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[1::198.162.10.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "1::198.162.10.255" + } + }, + "IPv6address trailing :: with IPv4: uri://[1:2:3:4:5::198.162.10.255]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[1:2:3:4:5::198.162.10.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "1:2:3:4:5::198.162.10.255" + } + }, + "IPv6address leading & trailing :: no IPv4: uri://[1::2]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[1::2]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "1::2" + } + }, + "IPv6address leading & trailing :: no IPv4: uri://[1:2:3:4:5:6::7]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[1:2:3:4:5:6::7]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "1:2:3:4:5:6::7" + } + }, + "IPv6address leading & trailing :: no IPv4: uri://[ffff:aaaa:bbbb::cccc:dddd:eeee:9999]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[ffff:aaaa:bbbb::cccc:dddd:eeee:9999]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "ffff:aaaa:bbbb::cccc:dddd:eeee:9999" + } + }, + "IPv6address leading & trailing :: with IPv4: uri://[1::2:198.162.10.255]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[1::2:198.162.10.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "1::2:198.162.10.255" + } + }, + "IPv6address leading & trailing :: with IPv4: uri://[1:2:3:4::7:198.162.10.255]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[1:2:3:4::7:198.162.10.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "1:2:3:4::7:198.162.10.255" + } + }, + "IPv6address leading & trailing :: with IPv4: uri://[ffff:aaaa:bbbb::cccc:dddd:198.162.10.255]": { + "msg": "service.org wants you to sign in with your Ethereum account:\n0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2\n\n\nURI: uri://[ffff:aaaa:bbbb::cccc:dddd:198.162.10.255]\nVersion: 1\nChain ID: 1\nNonce: 32891757\nIssued At: 2021-09-30T16:25:24.000Z", + "uri": { + "host": "ffff:aaaa:bbbb::cccc:dddd:198.162.10.255" + } + } +}