diff --git a/package-lock.json b/package-lock.json index 3b598d7..88b594d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,12 +12,13 @@ "@aws-sdk/client-s3": "^3.657.0", "@aws-sdk/client-ses": "^3.515.0", "@inquirer/prompts": "^7.2.0", - "@pretendonetwork/grpc": "^2.2.3", + "@pretendonetwork/grpc": "^2.5.4", "bcrypt": "^5.0.0", "buffer-crc32": "^0.2.13", "colors": "^1.4.0", "cors": "^2.8.5", "crc": "^4.3.2", + "cron": "^4.4.0", "dicer": "^0.2.5", "dotenv": "^16.0.3", "ejs": "^3.1.10", @@ -31,7 +32,6 @@ "image-pixels": "^1.1.1", "ip2location-nodejs": "^9.6.3", "is-valid-hostname": "^1.0.2", - "joi": "^17.8.3", "mii-js": "github:PretendoNetwork/mii-js#f1741e1f82771dd7c753fd408230373d33caa184", "moment": "^2.29.4", "mongoose": "^7.0.0", @@ -52,7 +52,7 @@ }, "devDependencies": { "@hcaptcha/types": "^1.0.3", - "@pretendonetwork/eslint-config": "^0.0.8", + "@pretendonetwork/eslint-config": "^0.1.4", "@types/bcrypt": "^5.0.0", "@types/buffer-crc32": "^0.2.2", "@types/cors": "^2.8.13", @@ -75,935 +75,354 @@ "typescript": "^4.9.5" } }, - "node_modules/@aws-crypto/crc32": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz", - "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==", + "node_modules/@aws-sdk/checksums": { + "version": "3.1000.17", + "resolved": "https://registry.npmjs.org/@aws-sdk/checksums/-/checksums-3.1000.17.tgz", + "integrity": "sha512-k45iXM7w8Pyknnz/vTXSS/IkLDNFdgnBQI7Hmq+uhsrW7NGT/BiUJGlv20QSKzihmH1XDvSCRILICaKi57/35w==", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", + "@aws-sdk/core": "^3.975.2", + "@aws-sdk/types": "^3.974.1", + "@smithy/core": "^3.29.3", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-crypto/crc32c": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/crc32c/-/crc32c-5.2.0.tgz", - "integrity": "sha512-+iWb8qaHLYKrNvGRbiYRHSdKRWhto5XlZUEBwDjYNf+ly5SVYG6zEoYIdxvf5R3zyeP16w4PLBn3rH1xc74Rag==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/sha1-browser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha1-browser/-/sha1-browser-5.2.0.tgz", - "integrity": "sha512-OH6lveCFfcDjX4dbAvCFSYUjJZjDr/3XJ3xHtjn3Oj5b9RjojQo8npoLeA/bNwkOkrSQ0wgrHzXk4tDRxGKJeg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/supports-web-crypto": "^5.2.0", - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha1-browser/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz", - "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-js": "^5.2.0", - "@aws-crypto/supports-web-crypto": "^5.2.0", - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "@aws-sdk/util-locate-window": "^3.0.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/sha256-js": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz", - "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/util": "^5.2.0", - "@aws-sdk/types": "^3.222.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=16.0.0" - } - }, - "node_modules/@aws-crypto/supports-web-crypto": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz", - "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/util": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz", - "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "^3.222.0", - "@smithy/util-utf8": "^2.0.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz", - "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz", - "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz", - "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^2.2.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=14.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/client-s3": { - "version": "3.832.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.832.0.tgz", - "integrity": "sha512-S+md1zCe71SEuaRDuLHq4mzhYYkVxR1ENa8NwrgInfYoC4xo8/pESoR6i0ZZpcLs0Jw4EyVInWYs4GgDHW70qQ==", + "version": "3.1087.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-s3/-/client-s3-3.1087.0.tgz", + "integrity": "sha512-44ua5vo5JiFFSnG3oeeWTMfSjOtblQSoJiGbf37s0W4Lr7IY9NmIVkBHIfD4hBI1VEKdvJhDmvuJawwTfi2pvw==", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/sha1-browser": "5.2.0", - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.830.0", - "@aws-sdk/middleware-bucket-endpoint": "3.830.0", - "@aws-sdk/middleware-expect-continue": "3.821.0", - "@aws-sdk/middleware-flexible-checksums": "3.826.0", - "@aws-sdk/middleware-host-header": "3.821.0", - "@aws-sdk/middleware-location-constraint": "3.821.0", - "@aws-sdk/middleware-logger": "3.821.0", - "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-sdk-s3": "3.826.0", - "@aws-sdk/middleware-ssec": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.828.0", - "@aws-sdk/region-config-resolver": "3.821.0", - "@aws-sdk/signature-v4-multi-region": "3.826.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.828.0", - "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.828.0", - "@aws-sdk/xml-builder": "3.821.0", - "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.3", - "@smithy/eventstream-serde-browser": "^4.0.4", - "@smithy/eventstream-serde-config-resolver": "^4.1.2", - "@smithy/eventstream-serde-node": "^4.0.4", - "@smithy/fetch-http-handler": "^5.0.4", - "@smithy/hash-blob-browser": "^4.0.4", - "@smithy/hash-node": "^4.0.4", - "@smithy/hash-stream-node": "^4.0.4", - "@smithy/invalid-dependency": "^4.0.4", - "@smithy/md5-js": "^4.0.4", - "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.11", - "@smithy/middleware-retry": "^4.1.12", - "@smithy/middleware-serde": "^4.0.8", - "@smithy/middleware-stack": "^4.0.4", - "@smithy/node-config-provider": "^4.1.3", - "@smithy/node-http-handler": "^4.0.6", - "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", - "@smithy/types": "^4.3.1", - "@smithy/url-parser": "^4.0.4", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.19", - "@smithy/util-defaults-mode-node": "^4.0.19", - "@smithy/util-endpoints": "^3.0.6", - "@smithy/util-middleware": "^4.0.4", - "@smithy/util-retry": "^4.0.5", - "@smithy/util-stream": "^4.2.2", - "@smithy/util-utf8": "^4.0.0", - "@smithy/util-waiter": "^4.0.5", - "@types/uuid": "^9.0.1", - "tslib": "^2.6.2", - "uuid": "^9.0.1" + "@aws-sdk/checksums": "^3.1000.17", + "@aws-sdk/core": "^3.975.2", + "@aws-sdk/credential-provider-node": "^3.972.68", + "@aws-sdk/middleware-sdk-s3": "^3.972.63", + "@aws-sdk/signature-v4-multi-region": "^3.996.40", + "@aws-sdk/types": "^3.974.1", + "@smithy/core": "^3.29.3", + "@smithy/fetch-http-handler": "^5.6.5", + "@smithy/node-http-handler": "^4.9.5", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/client-ses": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.830.0.tgz", - "integrity": "sha512-Y2XaJkqHJ7qM4cpCw3YS96fMZgT44mP3HLP+9dU0ct29L+iwf3zhigJGQzakieMdJfuTFZe7Vi6s1RbcWv5v5w==", + "version": "3.1087.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/client-ses/-/client-ses-3.1087.0.tgz", + "integrity": "sha512-mjJsyp0YMa9USrbnEnEecAjz64aBtH7j8fXbVb2LxwgWDPKhaa4zUZWzM97Yh8Gp5d/F4TOUK/jq2ywXC+B6lA==", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-node": "3.830.0", - "@aws-sdk/middleware-host-header": "3.821.0", - "@aws-sdk/middleware-logger": "3.821.0", - "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.828.0", - "@aws-sdk/region-config-resolver": "3.821.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.828.0", - "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.828.0", - "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.3", - "@smithy/fetch-http-handler": "^5.0.4", - "@smithy/hash-node": "^4.0.4", - "@smithy/invalid-dependency": "^4.0.4", - "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.11", - "@smithy/middleware-retry": "^4.1.12", - "@smithy/middleware-serde": "^4.0.8", - "@smithy/middleware-stack": "^4.0.4", - "@smithy/node-config-provider": "^4.1.3", - "@smithy/node-http-handler": "^4.0.6", - "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", - "@smithy/types": "^4.3.1", - "@smithy/url-parser": "^4.0.4", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.19", - "@smithy/util-defaults-mode-node": "^4.0.19", - "@smithy/util-endpoints": "^3.0.6", - "@smithy/util-middleware": "^4.0.4", - "@smithy/util-retry": "^4.0.5", - "@smithy/util-utf8": "^4.0.0", - "@smithy/util-waiter": "^4.0.5", + "@aws-sdk/core": "^3.975.2", + "@aws-sdk/credential-provider-node": "^3.972.68", + "@aws-sdk/types": "^3.974.1", + "@smithy/core": "^3.29.3", + "@smithy/fetch-http-handler": "^5.6.5", + "@smithy/node-http-handler": "^4.9.5", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/client-sso": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.830.0.tgz", - "integrity": "sha512-5zCEpfI+zwX2SIa258L+TItNbBoAvQQ6w74qdFM6YJufQ1F9tvwjTX8T+eSTT9nsFIvfYnUaGalWwJVfmJUgVQ==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.826.0", - "@aws-sdk/middleware-host-header": "3.821.0", - "@aws-sdk/middleware-logger": "3.821.0", - "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.828.0", - "@aws-sdk/region-config-resolver": "3.821.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.828.0", - "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.828.0", - "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.3", - "@smithy/fetch-http-handler": "^5.0.4", - "@smithy/hash-node": "^4.0.4", - "@smithy/invalid-dependency": "^4.0.4", - "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.11", - "@smithy/middleware-retry": "^4.1.12", - "@smithy/middleware-serde": "^4.0.8", - "@smithy/middleware-stack": "^4.0.4", - "@smithy/node-config-provider": "^4.1.3", - "@smithy/node-http-handler": "^4.0.6", - "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", - "@smithy/types": "^4.3.1", - "@smithy/url-parser": "^4.0.4", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.19", - "@smithy/util-defaults-mode-node": "^4.0.19", - "@smithy/util-endpoints": "^3.0.6", - "@smithy/util-middleware": "^4.0.4", - "@smithy/util-retry": "^4.0.5", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/core": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.826.0.tgz", - "integrity": "sha512-BGbQYzWj3ps+dblq33FY5tz/SsgJCcXX0zjQlSC07tYvU1jHTUvsefphyig+fY38xZ4wdKjbTop+KUmXUYrOXw==", + "version": "3.975.2", + "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.975.2.tgz", + "integrity": "sha512-iyeXwziyjJpixq5OmhsIyrSWx8vwcI7gDo4yRUC3EP7NQtOo9iAJiIEc3G+/HkhtNXqOhofiCK7Lc34Sq+fJWg==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/types": "3.821.0", - "@aws-sdk/xml-builder": "3.821.0", - "@smithy/core": "^3.5.3", - "@smithy/node-config-provider": "^4.1.3", - "@smithy/property-provider": "^4.0.4", - "@smithy/protocol-http": "^5.1.2", - "@smithy/signature-v4": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", - "@smithy/types": "^4.3.1", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-middleware": "^4.0.4", - "@smithy/util-utf8": "^4.0.0", - "fast-xml-parser": "4.4.1", + "@aws-sdk/types": "^3.974.1", + "@aws-sdk/xml-builder": "^3.972.35", + "@aws/lambda-invoke-store": "^0.3.0", + "@smithy/core": "^3.29.3", + "@smithy/signature-v4": "^5.6.3", + "@smithy/types": "^4.16.1", + "bowser": "^2.11.0", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-env": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.826.0.tgz", - "integrity": "sha512-DK3pQY8+iKK3MGDdC3uOZQ2psU01obaKlTYhEwNu4VWzgwQL4Vi3sWj4xSWGEK41vqZxiRLq6fOq7ysRI+qEZA==", + "version": "3.972.58", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.972.58.tgz", + "integrity": "sha512-vyGtvK1rY940eq7JT0yIGKuZ+2kpPSJcHibSvGlit5oiMFDamzC7cxBGLl4FLnd6suihMXDI2FSF2dL6TmBqPA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", - "@aws-sdk/types": "3.821.0", - "@smithy/property-provider": "^4.0.4", - "@smithy/types": "^4.3.1", + "@aws-sdk/core": "^3.975.2", + "@aws-sdk/types": "^3.974.1", + "@smithy/core": "^3.29.3", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-http": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.826.0.tgz", - "integrity": "sha512-N+IVZBh+yx/9GbMZTKO/gErBi/FYZQtcFRItoLbY+6WU+0cSWyZYfkoeOxHmQV3iX9k65oljERIWUmL9x6OSQg==", + "version": "3.972.60", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.972.60.tgz", + "integrity": "sha512-g9b9YzDrD5pcKiPBJfCSXRfFMrA39eR0guUhZ5SRm+7vMAVc43+effxbcamxBjSd5bUhrdKo5te/yQuWurLXLA==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", - "@aws-sdk/types": "3.821.0", - "@smithy/fetch-http-handler": "^5.0.4", - "@smithy/node-http-handler": "^4.0.6", - "@smithy/property-provider": "^4.0.4", - "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", - "@smithy/types": "^4.3.1", - "@smithy/util-stream": "^4.2.2", + "@aws-sdk/core": "^3.975.2", + "@aws-sdk/types": "^3.974.1", + "@smithy/core": "^3.29.3", + "@smithy/fetch-http-handler": "^5.6.5", + "@smithy/node-http-handler": "^4.9.5", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-ini": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.830.0.tgz", - "integrity": "sha512-zeQenzvh8JRY5nULd8izdjVGoCM1tgsVVsrLSwDkHxZTTW0hW/bmOmXfvdaE0wDdomXW7m2CkQDSmP7XdvNXZg==", + "version": "3.973.2", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.973.2.tgz", + "integrity": "sha512-Yr7yxNyQ8aHt9Ww0RPFUZx+xiem+vl7vuwhP0tniTijoesJNV5jou9HCgVpI0GEPAF+89TkOvilE5uRrZJnjaw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", - "@aws-sdk/credential-provider-env": "3.826.0", - "@aws-sdk/credential-provider-http": "3.826.0", - "@aws-sdk/credential-provider-process": "3.826.0", - "@aws-sdk/credential-provider-sso": "3.830.0", - "@aws-sdk/credential-provider-web-identity": "3.830.0", - "@aws-sdk/nested-clients": "3.830.0", - "@aws-sdk/types": "3.821.0", - "@smithy/credential-provider-imds": "^4.0.6", - "@smithy/property-provider": "^4.0.4", - "@smithy/shared-ini-file-loader": "^4.0.4", - "@smithy/types": "^4.3.1", + "@aws-sdk/core": "^3.975.2", + "@aws-sdk/credential-provider-env": "^3.972.58", + "@aws-sdk/credential-provider-http": "^3.972.60", + "@aws-sdk/credential-provider-login": "^3.972.64", + "@aws-sdk/credential-provider-process": "^3.972.58", + "@aws-sdk/credential-provider-sso": "^3.973.2", + "@aws-sdk/credential-provider-web-identity": "^3.972.64", + "@aws-sdk/nested-clients": "^3.997.32", + "@aws-sdk/types": "^3.974.1", + "@smithy/core": "^3.29.3", + "@smithy/credential-provider-imds": "^4.4.7", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" + } + }, + "node_modules/@aws-sdk/credential-provider-login": { + "version": "3.972.64", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-login/-/credential-provider-login-3.972.64.tgz", + "integrity": "sha512-YQoSI4d6kXvoenoG/0Jv/PqaAuukHzGmGXGyHBQYeEUNsYovlNAn/Sw1wp/WQbhcQ3HsEMGgjEahvD3igz6ecQ==", + "license": "Apache-2.0", + "dependencies": { + "@aws-sdk/core": "^3.975.2", + "@aws-sdk/nested-clients": "^3.997.32", + "@aws-sdk/types": "^3.974.1", + "@smithy/core": "^3.29.3", + "@smithy/types": "^4.16.1", + "tslib": "^2.6.2" + }, + "engines": { + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-node": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.830.0.tgz", - "integrity": "sha512-X/2LrTgwtK1pkWrvofxQBI8VTi6QVLtSMpsKKPPnJQ0vgqC0e4czSIs3ZxiEsOkCBaQ2usXSiKyh0ccsQ6k2OA==", + "version": "3.972.68", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.972.68.tgz", + "integrity": "sha512-4akjzW9CjorByYfqXBXmYUh/h7Io3U4DtVgGGh9TQraZ7ZlyJqNyHwDRGiUFnHD+BTOeTbCesCa4sJaK7BGZ7A==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/credential-provider-env": "3.826.0", - "@aws-sdk/credential-provider-http": "3.826.0", - "@aws-sdk/credential-provider-ini": "3.830.0", - "@aws-sdk/credential-provider-process": "3.826.0", - "@aws-sdk/credential-provider-sso": "3.830.0", - "@aws-sdk/credential-provider-web-identity": "3.830.0", - "@aws-sdk/types": "3.821.0", - "@smithy/credential-provider-imds": "^4.0.6", - "@smithy/property-provider": "^4.0.4", - "@smithy/shared-ini-file-loader": "^4.0.4", - "@smithy/types": "^4.3.1", + "@aws-sdk/credential-provider-env": "^3.972.58", + "@aws-sdk/credential-provider-http": "^3.972.60", + "@aws-sdk/credential-provider-ini": "^3.973.2", + "@aws-sdk/credential-provider-process": "^3.972.58", + "@aws-sdk/credential-provider-sso": "^3.973.2", + "@aws-sdk/credential-provider-web-identity": "^3.972.64", + "@aws-sdk/types": "^3.974.1", + "@smithy/core": "^3.29.3", + "@smithy/credential-provider-imds": "^4.4.7", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-process": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.826.0.tgz", - "integrity": "sha512-kURrc4amu3NLtw1yZw7EoLNEVhmOMRUTs+chaNcmS+ERm3yK0nKjaJzmKahmwlTQTSl3wJ8jjK7x962VPo+zWw==", + "version": "3.972.58", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.972.58.tgz", + "integrity": "sha512-1nYitRCaDmXWUrpBJt6WlcGjLx1JVsMY8rlYuHHsTYTSaYikbixYdQSyINN2VYq1F798uTO9qHAzytL25M8g3A==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", - "@aws-sdk/types": "3.821.0", - "@smithy/property-provider": "^4.0.4", - "@smithy/shared-ini-file-loader": "^4.0.4", - "@smithy/types": "^4.3.1", + "@aws-sdk/core": "^3.975.2", + "@aws-sdk/types": "^3.974.1", + "@smithy/core": "^3.29.3", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-sso": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.830.0.tgz", - "integrity": "sha512-+VdRpZmfekzpySqZikAKx6l5ndnLGluioIgUG4ZznrButgFD/iogzFtGmBDFB3ZLViX1l4pMXru0zFwJEZT21Q==", + "version": "3.973.2", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.973.2.tgz", + "integrity": "sha512-pjMLaLU/JZi5lVfmR14V1OZqRBTuMHf6AwGNZA0K9hK+JKtO3jcLBarfD8iq5oc8cSowvc/9R32sqMVXZPo6xQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/client-sso": "3.830.0", - "@aws-sdk/core": "3.826.0", - "@aws-sdk/token-providers": "3.830.0", - "@aws-sdk/types": "3.821.0", - "@smithy/property-provider": "^4.0.4", - "@smithy/shared-ini-file-loader": "^4.0.4", - "@smithy/types": "^4.3.1", + "@aws-sdk/core": "^3.975.2", + "@aws-sdk/nested-clients": "^3.997.32", + "@aws-sdk/token-providers": "3.1087.0", + "@aws-sdk/types": "^3.974.1", + "@smithy/core": "^3.29.3", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/credential-provider-web-identity": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.830.0.tgz", - "integrity": "sha512-hPYrKsZeeOdLROJ59T6Y8yZ0iwC/60L3qhZXjapBFjbqBtMaQiMTI645K6xVXBioA6vxXq7B4aLOhYqk6Fy/Ww==", + "version": "3.972.64", + "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.972.64.tgz", + "integrity": "sha512-7Buc7p0OvDHW7iBsu4b+YdS0WnaFBDGKDfbVQqaac9dkWiSiUtIoarBDsA1RmOVXZijaZJDoHJFIQiicQvWRlQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", - "@aws-sdk/nested-clients": "3.830.0", - "@aws-sdk/types": "3.821.0", - "@smithy/property-provider": "^4.0.4", - "@smithy/types": "^4.3.1", + "@aws-sdk/core": "^3.975.2", + "@aws-sdk/nested-clients": "^3.997.32", + "@aws-sdk/types": "^3.974.1", + "@smithy/core": "^3.29.3", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/middleware-bucket-endpoint": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-bucket-endpoint/-/middleware-bucket-endpoint-3.830.0.tgz", - "integrity": "sha512-ElVeCReZSH5Ds+/pkL5ebneJjuo8f49e9JXV1cYizuH0OAOQfYaBU9+M+7+rn61pTttOFE8W//qKzrXBBJhfMg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-arn-parser": "3.804.0", - "@smithy/node-config-provider": "^4.1.3", - "@smithy/protocol-http": "^5.1.2", - "@smithy/types": "^4.3.1", - "@smithy/util-config-provider": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/middleware-expect-continue": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-expect-continue/-/middleware-expect-continue-3.821.0.tgz", - "integrity": "sha512-zAOoSZKe1njOrtynvK6ZORU57YGv5I7KP4+rwOvUN3ZhJbQ7QPf8gKtFUCYAPRMegaXCKF/ADPtDZBAmM+zZ9g==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.821.0", - "@smithy/protocol-http": "^5.1.2", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/middleware-flexible-checksums": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-flexible-checksums/-/middleware-flexible-checksums-3.826.0.tgz", - "integrity": "sha512-Fz9w8CFYPfSlHEB6feSsi06hdS+s+FB8k5pO4L7IV0tUa78mlhxF/VNlAJaVWYyOkZXl4HPH2K48aapACSQOXw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/crc32": "5.2.0", - "@aws-crypto/crc32c": "5.2.0", - "@aws-crypto/util": "5.2.0", - "@aws-sdk/core": "3.826.0", - "@aws-sdk/types": "3.821.0", - "@smithy/is-array-buffer": "^4.0.0", - "@smithy/node-config-provider": "^4.1.3", - "@smithy/protocol-http": "^5.1.2", - "@smithy/types": "^4.3.1", - "@smithy/util-middleware": "^4.0.4", - "@smithy/util-stream": "^4.2.2", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/middleware-host-header": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.821.0.tgz", - "integrity": "sha512-xSMR+sopSeWGx5/4pAGhhfMvGBHioVBbqGvDs6pG64xfNwM5vq5s5v6D04e2i+uSTj4qGa71dLUs5I0UzAK3sw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.821.0", - "@smithy/protocol-http": "^5.1.2", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/middleware-location-constraint": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-location-constraint/-/middleware-location-constraint-3.821.0.tgz", - "integrity": "sha512-sKrm80k0t3R0on8aA/WhWFoMaAl4yvdk+riotmMElLUpcMcRXAd1+600uFVrxJqZdbrKQ0mjX0PjT68DlkYXLg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.821.0", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/middleware-logger": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.821.0.tgz", - "integrity": "sha512-0cvI0ipf2tGx7fXYEEN5fBeZDz2RnHyb9xftSgUsEq7NBxjV0yTZfLJw6Za5rjE6snC80dRN8+bTNR1tuG89zA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.821.0", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/middleware-recursion-detection": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.821.0.tgz", - "integrity": "sha512-efmaifbhBoqKG3bAoEfDdcM8hn1psF+4qa7ykWuYmfmah59JBeqHLfz5W9m9JoTwoKPkFcVLWZxnyZzAnVBOIg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.821.0", - "@smithy/protocol-http": "^5.1.2", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/middleware-sdk-s3": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.826.0.tgz", - "integrity": "sha512-8F0qWaYKfvD/de1AKccXuigM+gb/IZSncCqxdnFWqd+TFzo9qI9Hh+TpUhWOMYSgxsMsYQ8ipmLzlD/lDhjrmA==", + "version": "3.972.63", + "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-sdk-s3/-/middleware-sdk-s3-3.972.63.tgz", + "integrity": "sha512-EklitJscj/Aq2Pk8nz0xSxvL+VMSP29iFqouQU0Ow05JKn5y/OhI81ujkfVS72MjD1yeoU9uIdT8c/W6vhktQw==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-arn-parser": "3.804.0", - "@smithy/core": "^3.5.3", - "@smithy/node-config-provider": "^4.1.3", - "@smithy/protocol-http": "^5.1.2", - "@smithy/signature-v4": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", - "@smithy/types": "^4.3.1", - "@smithy/util-config-provider": "^4.0.0", - "@smithy/util-middleware": "^4.0.4", - "@smithy/util-stream": "^4.2.2", - "@smithy/util-utf8": "^4.0.0", + "@aws-sdk/core": "^3.975.2", + "@aws-sdk/signature-v4-multi-region": "^3.996.40", + "@aws-sdk/types": "^3.974.1", + "@smithy/core": "^3.29.3", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/middleware-ssec": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-ssec/-/middleware-ssec-3.821.0.tgz", - "integrity": "sha512-YYi1Hhr2AYiU/24cQc8HIB+SWbQo6FBkMYojVuz/zgrtkFmALxENGF/21OPg7f/QWd+eadZJRxCjmRwh5F2Cxg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.821.0", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/middleware-user-agent": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.828.0.tgz", - "integrity": "sha512-nixvI/SETXRdmrVab4D9LvXT3lrXkwAWGWk2GVvQvzlqN1/M/RfClj+o37Sn4FqRkGH9o9g7Fqb1YqZ4mqDAtA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/core": "3.826.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.828.0", - "@smithy/core": "^3.5.3", - "@smithy/protocol-http": "^5.1.2", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/nested-clients": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.830.0.tgz", - "integrity": "sha512-5N5YTlBr1vtxf7+t+UaIQ625KEAmm7fY9o1e3MgGOi/paBoI0+axr3ud24qLIy0NSzFlAHEaxUSWxcERNjIoZw==", + "version": "3.997.32", + "resolved": "https://registry.npmjs.org/@aws-sdk/nested-clients/-/nested-clients-3.997.32.tgz", + "integrity": "sha512-6Yj2fr9XF67cndITea48rchTdVr3VGx6PN47bIKNinJAjLkmaIlz/4EBPCgJ8UmhVopiXmeAuPLI3+DXDDbMhQ==", "license": "Apache-2.0", "dependencies": { - "@aws-crypto/sha256-browser": "5.2.0", - "@aws-crypto/sha256-js": "5.2.0", - "@aws-sdk/core": "3.826.0", - "@aws-sdk/middleware-host-header": "3.821.0", - "@aws-sdk/middleware-logger": "3.821.0", - "@aws-sdk/middleware-recursion-detection": "3.821.0", - "@aws-sdk/middleware-user-agent": "3.828.0", - "@aws-sdk/region-config-resolver": "3.821.0", - "@aws-sdk/types": "3.821.0", - "@aws-sdk/util-endpoints": "3.828.0", - "@aws-sdk/util-user-agent-browser": "3.821.0", - "@aws-sdk/util-user-agent-node": "3.828.0", - "@smithy/config-resolver": "^4.1.4", - "@smithy/core": "^3.5.3", - "@smithy/fetch-http-handler": "^5.0.4", - "@smithy/hash-node": "^4.0.4", - "@smithy/invalid-dependency": "^4.0.4", - "@smithy/middleware-content-length": "^4.0.4", - "@smithy/middleware-endpoint": "^4.1.11", - "@smithy/middleware-retry": "^4.1.12", - "@smithy/middleware-serde": "^4.0.8", - "@smithy/middleware-stack": "^4.0.4", - "@smithy/node-config-provider": "^4.1.3", - "@smithy/node-http-handler": "^4.0.6", - "@smithy/protocol-http": "^5.1.2", - "@smithy/smithy-client": "^4.4.3", - "@smithy/types": "^4.3.1", - "@smithy/url-parser": "^4.0.4", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-body-length-node": "^4.0.0", - "@smithy/util-defaults-mode-browser": "^4.0.19", - "@smithy/util-defaults-mode-node": "^4.0.19", - "@smithy/util-endpoints": "^3.0.6", - "@smithy/util-middleware": "^4.0.4", - "@smithy/util-retry": "^4.0.5", - "@smithy/util-utf8": "^4.0.0", + "@aws-sdk/core": "^3.975.2", + "@aws-sdk/signature-v4-multi-region": "^3.996.40", + "@aws-sdk/types": "^3.974.1", + "@smithy/core": "^3.29.3", + "@smithy/fetch-http-handler": "^5.6.5", + "@smithy/node-http-handler": "^4.9.5", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/region-config-resolver": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.821.0.tgz", - "integrity": "sha512-t8og+lRCIIy5nlId0bScNpCkif8sc0LhmtaKsbm0ZPm3sCa/WhCbSZibjbZ28FNjVCV+p0D9RYZx0VDDbtWyjw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.821.0", - "@smithy/node-config-provider": "^4.1.3", - "@smithy/types": "^4.3.1", - "@smithy/util-config-provider": "^4.0.0", - "@smithy/util-middleware": "^4.0.4", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/signature-v4-multi-region": { - "version": "3.826.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.826.0.tgz", - "integrity": "sha512-3fEi/zy6tpMzomYosksGtu7jZqGFcdBXoL7YRsG7OEeQzBbOW9B+fVaQZ4jnsViSjzA/yKydLahMrfPnt+iaxg==", + "version": "3.996.40", + "resolved": "https://registry.npmjs.org/@aws-sdk/signature-v4-multi-region/-/signature-v4-multi-region-3.996.40.tgz", + "integrity": "sha512-wrGZ/authosokclY1DXsiWT/1WjfCI22FuZGgdcilF+XLTXs5dCjAtiFYSPsEToZkbm3Lj2YP8PoWg0yoMNu0g==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/middleware-sdk-s3": "3.826.0", - "@aws-sdk/types": "3.821.0", - "@smithy/protocol-http": "^5.1.2", - "@smithy/signature-v4": "^5.1.2", - "@smithy/types": "^4.3.1", + "@aws-sdk/types": "^3.974.1", + "@smithy/signature-v4": "^5.6.3", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/token-providers": { - "version": "3.830.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.830.0.tgz", - "integrity": "sha512-aJ4guFwj92nV9D+EgJPaCFKK0I3y2uMchiDfh69Zqnmwfxxxfxat6F79VA7PS0BdbjRfhLbn+Ghjftnomu2c1g==", + "version": "3.1087.0", + "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.1087.0.tgz", + "integrity": "sha512-umM+qNq16f2fH+VLM5MqXW4ORNQAjk+TOSto73xbUHcKaU41L48j786r3UWQYlejeJk37NlvRYgxBT+MBkfaYQ==", "license": "Apache-2.0", "dependencies": { - "@aws-sdk/core": "3.826.0", - "@aws-sdk/nested-clients": "3.830.0", - "@aws-sdk/types": "3.821.0", - "@smithy/property-provider": "^4.0.4", - "@smithy/shared-ini-file-loader": "^4.0.4", - "@smithy/types": "^4.3.1", + "@aws-sdk/core": "^3.975.2", + "@aws-sdk/nested-clients": "^3.997.32", + "@aws-sdk/types": "^3.974.1", + "@smithy/core": "^3.29.3", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/types": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.821.0.tgz", - "integrity": "sha512-Znroqdai1a90TlxGaJ+FK1lwC0fHpo97Xjsp5UKGR5JODYm7f9+/fF17ebO1KdoBr/Rm0UIFiF5VmI8ts9F1eA==", + "version": "3.974.1", + "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.974.1.tgz", + "integrity": "sha512-W0IQZR0eaBqlBFIIofMapaWkw1W0U+Xi4dvW+BqwmCEMd8Ng2U6IhkxuPSjMVnR8klLjfuS9PeZWUl1N6UaZdg==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.3.1", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/util-arn-parser": { - "version": "3.804.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-arn-parser/-/util-arn-parser-3.804.0.tgz", - "integrity": "sha512-wmBJqn1DRXnZu3b4EkE6CWnoWMo1ZMvlfkqU5zPz67xx1GMaXlDCchFvKAXMjk4jn/L1O3tKnoFDNsoLV1kgNQ==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/util-endpoints": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.828.0.tgz", - "integrity": "sha512-RvKch111SblqdkPzg3oCIdlGxlQs+k+P7Etory9FmxPHyPDvsP1j1c74PmgYqtzzMWmoXTjd+c9naUHh9xG8xg==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.821.0", - "@smithy/types": "^4.3.1", - "@smithy/util-endpoints": "^3.0.6", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/util-locate-window": { - "version": "3.804.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.804.0.tgz", - "integrity": "sha512-zVoRfpmBVPodYlnMjgVjfGoEZagyRF5IPn3Uo6ZvOZp24chnW/FRstH7ESDHDDRga4z3V+ElUQHKpFDXWyBW5A==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@aws-sdk/util-user-agent-browser": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.821.0.tgz", - "integrity": "sha512-irWZHyM0Jr1xhC+38OuZ7JB6OXMLPZlj48thElpsO1ZSLRkLZx5+I7VV6k3sp2yZ7BYbKz/G2ojSv4wdm7XTLw==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/types": "3.821.0", - "@smithy/types": "^4.3.1", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - } - }, - "node_modules/@aws-sdk/util-user-agent-node": { - "version": "3.828.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.828.0.tgz", - "integrity": "sha512-LdN6fTBzTlQmc8O8f1wiZN0qF3yBWVGis7NwpWK7FUEzP9bEZRxYfIkV9oV9zpt6iNRze1SedK3JQVB/udxBoA==", - "license": "Apache-2.0", - "dependencies": { - "@aws-sdk/middleware-user-agent": "3.828.0", - "@aws-sdk/types": "3.821.0", - "@smithy/node-config-provider": "^4.1.3", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - }, - "peerDependencies": { - "aws-crt": ">=1.0.0" - }, - "peerDependenciesMeta": { - "aws-crt": { - "optional": true - } + "node": ">=20.0.0" } }, "node_modules/@aws-sdk/xml-builder": { - "version": "3.821.0", - "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.821.0.tgz", - "integrity": "sha512-DIIotRnefVL6DiaHtO6/21DhJ4JZnnIwdNbpwiAhdt/AVbttcE4yw925gsjur0OGv5BTYXQXU3YnANBYnZjuQA==", + "version": "3.972.35", + "resolved": "https://registry.npmjs.org/@aws-sdk/xml-builder/-/xml-builder-3.972.35.tgz", + "integrity": "sha512-pXzaWe3evZhjxDXAlMnqISe/XefTCGwBJG4nFTXaWSgAnMkqPEhxEPqJNhhpGesEvKFhvNpnozJJ4GTL11bRYw==", "license": "Apache-2.0", "dependencies": { - "@smithy/types": "^4.3.1", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, + "engines": { + "node": ">=20.0.0" + } + }, + "node_modules/@aws/lambda-invoke-store": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@aws/lambda-invoke-store/-/lambda-invoke-store-0.3.0.tgz", + "integrity": "sha512-sl4Bm6yiMNYrZKkqqDFWN0UfnWhlS8ivKxrYl+6t0gCLrqr8y3B2IqZZbFRkfaVVp7C/baApyh71P+LeE1A2sQ==", + "license": "Apache-2.0", "engines": { "node": ">=18.0.0" } }, "node_modules/@bufbuild/protobuf": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.5.2.tgz", - "integrity": "sha512-foZ7qr0IsUBjzWIq+SuBLfdQCpJ1j8cTuNNT4owngTHoN5KsJb8L9t65fzz7SCeSWzescoOil/0ldqiL041ABg==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-2.2.2.tgz", + "integrity": "sha512-UNtPCbrwrenpmrXuRwn9jYpPoweNXj8X5sMvYgsqYyaH8jQ6LfUJSk3dJLnBK+6sfYPrF4iAIo5sd5HQ+tg75A==", "license": "(Apache-2.0 AND BSD-3-Clause)" }, "node_modules/@emnapi/core": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.4.3.tgz", - "integrity": "sha512-4m62DuCE07lw01soJwPiBGC0nAww0Q+RY70VZ+n49yDIO13yyinhbWCeNnaob0lakDtWQzSdtNWzJeOJt2ma+g==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.10.0.tgz", + "integrity": "sha512-yq6OkJ4p82CAfPl0u9mQebQHKPJkY7WrIuk205cTYnYe+k2Z8YBh11FrbRG/H6ihirqcacOgl2BIO8oyMQLeXw==", "license": "MIT", "optional": true, "dependencies": { - "@emnapi/wasi-threads": "1.0.2", + "@emnapi/wasi-threads": "1.2.1", "tslib": "^2.4.0" } }, "node_modules/@emnapi/runtime": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.4.3.tgz", - "integrity": "sha512-pBPWdu6MLKROBX05wSNKcNb++m5Er+KQ9QkB+WVM+pW2Kx9hoSrVTnu3BdkI5eBLZoKu/J6mW/B6i6bJB2ytXQ==", + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.10.0.tgz", + "integrity": "sha512-ewvYlk86xUoGI0zQRNq/mC+16R1QeDlKQy21Ki3oSYXNgLb45GV1P6A0M+/s6nyCuNDqe5VpaY84BzXGwVbwFA==", "license": "MIT", "optional": true, "dependencies": { @@ -1011,9 +430,9 @@ } }, "node_modules/@emnapi/wasi-threads": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.0.2.tgz", - "integrity": "sha512-5n3nTJblwRi8LlXkJ9eBzu+kZR8Yxcc7ubakyQTFzPMtIhFpUBRbsnc2Dv88IZDIbCDlBiWrknhB4Lsz7mg6BA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz", + "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==", "license": "MIT", "optional": true, "dependencies": { @@ -1021,14 +440,14 @@ } }, "node_modules/@eslint-community/eslint-plugin-eslint-comments": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.5.0.tgz", - "integrity": "sha512-MAhuTKlr4y/CE3WYX26raZjy+I/kS2PLKSzvfmDCGrBLTFHOYwqROZdr4XwPgXwX3K9rjzMr4pSmUWGnzsUyMg==", + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-plugin-eslint-comments/-/eslint-plugin-eslint-comments-4.7.2.tgz", + "integrity": "sha512-LF03qURSwEWm2dz5wtdDCzNk+7Opl0X7q6I3undsaIuNsEiNvRV3BCtqu14Q/6Pzg1tBj44LcxpW2EpSLZStZw==", "dev": true, "license": "MIT", "dependencies": { "escape-string-regexp": "^4.0.0", - "ignore": "^5.2.4" + "ignore": "^7.0.5" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1037,13 +456,13 @@ "url": "https://opencollective.com/eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0 || ^10.0.0" } }, "node_modules/@eslint-community/eslint-utils": { - "version": "4.7.0", - "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.7.0.tgz", - "integrity": "sha512-dyybb3AcajC7uha6CvhdVRJqaKyn7w2YKqKyAN37NKYgZT36w+iRb0Dymmc5qEJ549c/S31cMMSFd75bteCpCw==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz", + "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==", "dev": true, "license": "MIT", "dependencies": { @@ -1073,9 +492,9 @@ } }, "node_modules/@eslint-community/regexpp": { - "version": "4.12.1", - "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz", - "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==", + "version": "4.12.2", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz", + "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==", "dev": true, "license": "MIT", "engines": { @@ -1083,24 +502,31 @@ } }, "node_modules/@eslint/config-array": { - "version": "0.20.1", - "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.20.1.tgz", - "integrity": "sha512-OL0RJzC/CBzli0DrrR31qzj6d6i6Mm3HByuhflhl4LOBiWxN+3i6/t/ZQQNii4tjksXi8r2CRW1wMpWA2ULUEw==", + "version": "0.21.2", + "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz", + "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/object-schema": "^2.1.6", + "@eslint/object-schema": "^2.1.7", "debug": "^4.3.1", - "minimatch": "^3.1.2" + "minimatch": "^3.1.5" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, + "node_modules/@eslint/config-array/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/@eslint/config-array/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -1109,9 +535,9 @@ } }, "node_modules/@eslint/config-array/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -1122,19 +548,22 @@ } }, "node_modules/@eslint/config-helpers": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.2.3.tgz", - "integrity": "sha512-u180qk2Um1le4yf0ruXH3PYFeEZeYC3p/4wCTKrr2U1CmGdzGi3KtY0nuPDH48UJxlKCC5RDzbcbh4X0XlqgHg==", + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz", + "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@eslint/core": "^0.17.0" + }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, "node_modules/@eslint/core": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.14.0.tgz", - "integrity": "sha512-qIbV0/JZr7iSDjqAc60IqbLdsj9GDt16xQtWD+B78d/HAlvysGdZZ6rpJHGAc2T0FQx1X6thsSPdnoiGKdNtdg==", + "version": "0.17.0", + "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz", + "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==", "dev": true, "license": "Apache-2.0", "dependencies": { @@ -1145,20 +574,20 @@ } }, "node_modules/@eslint/eslintrc": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.1.tgz", - "integrity": "sha512-gtF186CXhIl1p4pJNGZw8Yc6RlshoePRvE0X91oPGb3vZ8pM3qOS9W9NGPat9LziaBV7XrJWGylNQXkGcnM3IQ==", + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.6.tgz", + "integrity": "sha512-l2Ul9PrHsPCKcEY/ac7VgFj9D80C7S68sOKc618SyHDPK36s1XcFebXY0iTzUVn4Yq+YbwvSnDmCz9yxjX+QrA==", "dev": true, "license": "MIT", "dependencies": { - "ajv": "^6.12.4", + "ajv": "^6.14.0", "debug": "^4.3.2", "espree": "^10.0.1", "globals": "^14.0.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", + "js-yaml": "^4.3.0", + "minimatch": "^3.1.5", "strip-json-comments": "^3.1.1" }, "engines": { @@ -1168,10 +597,17 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -1192,10 +628,20 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/@eslint/eslintrc/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/@eslint/eslintrc/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -1206,9 +652,9 @@ } }, "node_modules/@eslint/js": { - "version": "9.29.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.29.0.tgz", - "integrity": "sha512-3PIF4cBw/y+1u2EazflInpV+lYsSG0aByVIQzAgb1m1MhHFSbqTyNqtBKHgWf/9Ykud+DhILS9EGkmekVhbKoQ==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.5.tgz", + "integrity": "sha512-QywQuszQh77pIXCsq998c8hbhSTI/azTty1Z6N53dmAudKHhy573j3yvRLsX2BSp8YpLtoCEG8E9DJe+8zUh4A==", "dev": true, "license": "MIT", "engines": { @@ -1219,9 +665,9 @@ } }, "node_modules/@eslint/object-schema": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz", - "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==", + "version": "2.1.7", + "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz", + "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -1229,39 +675,26 @@ } }, "node_modules/@eslint/plugin-kit": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.3.5.tgz", - "integrity": "sha512-Z5kJ+wU3oA7MMIqVR9tyZRtjYPr4OC004Q4Rw7pgOKUOKkJfZ3O24nz3WYfGRpMDNmcOi3TwQOmgm7B7Tpii0w==", + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz", + "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@eslint/core": "^0.15.2", + "@eslint/core": "^0.17.0", "levn": "^0.4.1" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" } }, - "node_modules/@eslint/plugin-kit/node_modules/@eslint/core": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.15.2.tgz", - "integrity": "sha512-78Md3/Rrxh83gCxoUc0EiciuOHsIITzLy53m3d9UyiW8y9Dj2D29FeETqyKA+BRK76tnTp6RXWb3pCay8Oyomg==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@types/json-schema": "^7.0.15" - }, - "engines": { - "node": "^18.18.0 || ^20.9.0 || >=21.1.0" - } - }, "node_modules/@grpc/grpc-js": { - "version": "1.13.4", - "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.13.4.tgz", - "integrity": "sha512-GsFaMXCkMqkKIvwCQjCrwH+GHbPKBjhwo/8ZuUkWHqbI73Kky9I+pQltrlT0+MWpedCoosda53lgjYfyEPgxBg==", + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.14.4.tgz", + "integrity": "sha512-k9Dj3DV/itK9D06Y8f190Qgop7/Ui+D0njFV3LHMPwPT75DpXLQohE9Wmz0QElrJnzsjB7KPWiKJbOl7IPDArQ==", "license": "Apache-2.0", "dependencies": { - "@grpc/proto-loader": "^0.7.13", + "@grpc/proto-loader": "^0.8.0", "@js-sdsl/ordered-map": "^4.4.2" }, "engines": { @@ -1269,14 +702,14 @@ } }, "node_modules/@grpc/proto-loader": { - "version": "0.7.15", - "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.15.tgz", - "integrity": "sha512-tMXdRCfYVixjuFK+Hk0Q1s38gV9zDiDJfWL3h1rv4Qc39oILCu1TRTDt7+fGUI8K4G1Fj125Hx/ru3azECWTyQ==", + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.8.1.tgz", + "integrity": "sha512-wtF6h+DY6M3YaDBPAmvuuA6jV8Sif9MjtOI5euKFWRgCDl5PeDpPsHR9u2l6St5ceY8AZgoNDww5+HvEsXFsGg==", "license": "Apache-2.0", "dependencies": { "lodash.camelcase": "^4.3.0", "long": "^5.0.0", - "protobufjs": "^7.2.5", + "protobufjs": "^7.5.5", "yargs": "^17.7.2" }, "bin": { @@ -1318,9 +751,9 @@ } }, "node_modules/@grpc/proto-loader/node_modules/yargs": { - "version": "17.7.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", - "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "version": "17.7.3", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.3.tgz", + "integrity": "sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==", "license": "MIT", "dependencies": { "cliui": "^8.0.1", @@ -1344,64 +777,49 @@ "node": ">=12" } }, - "node_modules/@hapi/hoek": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.3.0.tgz", - "integrity": "sha512-/c6rf4UJlmHlC9b5BaNvzAcFv7HZ2QHaV0D4/HNlBdvFnvQq8RI4kYdhyPCl7Xj+oWvTWQ8ujhqS53LIgAe6KQ==", - "license": "BSD-3-Clause" - }, - "node_modules/@hapi/topo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/@hapi/topo/-/topo-5.1.0.tgz", - "integrity": "sha512-foQZKJig7Ob0BMAYBfcJk8d77QtOe7Wo4ox7ff1lQYoNNAb6jwcY1ncdoy2e9wQZzvNy7ODZCYJkK8kzmcAnAg==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, "node_modules/@hcaptcha/types": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@hcaptcha/types/-/types-1.0.4.tgz", - "integrity": "sha512-4CBrdr9DFC7sYZPRvLol82UVZVne8B2skBGfMDUqPC6q9vzHMwv/cNxXW44EIa6DaFDr+EWNSnKJpHxWr7Q42Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@hcaptcha/types/-/types-1.2.0.tgz", + "integrity": "sha512-lyeAbHCsrPS/uf5bwKr1WmhVduEHMe+2yUg5TnpDeKAgP+Nr/GyiZjp7zgSwm0ECD9e/r0OJFo/hz4DIYQUOQw==", "dev": true, "license": "MIT" }, "node_modules/@humanfs/core": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", - "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.2.tgz", + "integrity": "sha512-UhXNm+CFMWcbChXywFwkmhqjs3PRCmcSa/hfBgLIb7oQ5HNb1wS0icWsGtSAUNgefHeI+eBrA8I1fxmbHsGdvA==", "dev": true, "license": "Apache-2.0", + "dependencies": { + "@humanfs/types": "^0.15.0" + }, "engines": { "node": ">=18.18.0" } }, "node_modules/@humanfs/node": { - "version": "0.16.6", - "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz", - "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==", + "version": "0.16.8", + "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.8.tgz", + "integrity": "sha512-gE1eQNZ3R++kTzFUpdGlpmy8kDZD/MLyHqDwqjkVQI0JMdI1D51sy1H958PNXYkM2rAac7e5/CnIKZrHtPh3BQ==", "dev": true, "license": "Apache-2.0", "dependencies": { - "@humanfs/core": "^0.19.1", - "@humanwhocodes/retry": "^0.3.0" + "@humanfs/core": "^0.19.2", + "@humanfs/types": "^0.15.0", + "@humanwhocodes/retry": "^0.4.0" }, "engines": { "node": ">=18.18.0" } }, - "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz", - "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==", + "node_modules/@humanfs/types": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/@humanfs/types/-/types-0.15.0.tgz", + "integrity": "sha512-ZZ1w0aoQkwuUuC7Yf+7sdeaNfqQiiLcSRbfI08oAxqLtpXQr9AIVX7Ay7HLDuiLYAaFPu8oBYNq/QIi9URHJ3Q==", "dev": true, "license": "Apache-2.0", "engines": { - "node": ">=18.18" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" + "node": ">=18.18.0" } }, "node_modules/@humanwhocodes/module-importer": { @@ -1433,25 +851,25 @@ } }, "node_modules/@inquirer/ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.0.tgz", - "integrity": "sha512-JWaTfCxI1eTmJ1BIv86vUfjVatOdxwD0DAVKYevY8SazeUUZtW+tNbsdejVO1GYE0GXJW1N1ahmiC3TFd+7wZA==", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@inquirer/ansi/-/ansi-1.0.2.tgz", + "integrity": "sha512-S8qNSZiYzFd0wAcyG5AXCvUHC5Sr7xpZ9wZ2py9XR88jUz8wooStVx5M6dRzczbBWjic9NP7+rY0Xi7qqK/aMQ==", "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@inquirer/checkbox": { - "version": "4.1.8", - "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.1.8.tgz", - "integrity": "sha512-d/QAsnwuHX2OPolxvYcgSj7A9DO9H6gVOy2DvBTx+P2LH2iRTo/RSGV3iwCzW024nP9hw98KIuDmdyhZQj1UQg==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/checkbox/-/checkbox-4.3.2.tgz", + "integrity": "sha512-VXukHf0RR1doGe6Sm4F0Em7SWYLTHSsbGfJdS9Ja2bX5/D5uwVOEjr07cncLROdBvmnvCATYEWlHqYmXv2IlQA==", "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/figures": "^1.0.12", - "@inquirer/type": "^3.0.7", - "ansi-escapes": "^4.3.2", - "yoctocolors-cjs": "^2.1.2" + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { "node": ">=18" @@ -1466,13 +884,13 @@ } }, "node_modules/@inquirer/confirm": { - "version": "5.1.12", - "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.12.tgz", - "integrity": "sha512-dpq+ielV9/bqgXRUbNH//KsY6WEw9DrGPmipkpmgC1Y46cwuBTNx7PXFWTjc3MQ+urcc0QxoVHcMI0FW4Ok0hg==", + "version": "5.1.21", + "resolved": "https://registry.npmjs.org/@inquirer/confirm/-/confirm-5.1.21.tgz", + "integrity": "sha512-KR8edRkIsUayMXV+o3Gv+q4jlhENF9nMYUZs9PA2HzrXeHI8M5uDag70U7RJn9yyiMZSbtF5/UexBtAVtZGSbQ==", "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/type": "^3.0.7" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { "node": ">=18" @@ -1487,19 +905,19 @@ } }, "node_modules/@inquirer/core": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.2.2.tgz", - "integrity": "sha512-yXq/4QUnk4sHMtmbd7irwiepjB8jXU0kkFRL4nr/aDBA2mDz13cMakEWdDwX3eSCTkk03kwcndD1zfRAIlELxA==", + "version": "10.3.2", + "resolved": "https://registry.npmjs.org/@inquirer/core/-/core-10.3.2.tgz", + "integrity": "sha512-43RTuEbfP8MbKzedNqBrlhhNKVwoK//vUFNW3Q3vZ88BLcrs4kYpGg+B2mm5p2K/HfygoCxuKwJJiv8PbGmE0A==", "license": "MIT", "dependencies": { - "@inquirer/ansi": "^1.0.0", - "@inquirer/figures": "^1.0.13", - "@inquirer/type": "^3.0.8", + "@inquirer/ansi": "^1.0.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", "cli-width": "^4.1.0", "mute-stream": "^2.0.0", "signal-exit": "^4.1.0", "wrap-ansi": "^6.2.0", - "yoctocolors-cjs": "^2.1.2" + "yoctocolors-cjs": "^2.1.3" }, "engines": { "node": ">=18" @@ -1514,14 +932,14 @@ } }, "node_modules/@inquirer/editor": { - "version": "4.2.20", - "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.20.tgz", - "integrity": "sha512-7omh5y5bK672Q+Brk4HBbnHNowOZwrb/78IFXdrEB9PfdxL3GudQyDk8O9vQ188wj3xrEebS2M9n18BjJoI83g==", + "version": "4.2.23", + "resolved": "https://registry.npmjs.org/@inquirer/editor/-/editor-4.2.23.tgz", + "integrity": "sha512-aLSROkEwirotxZ1pBaP8tugXRFCxW94gwrQLxXfrZsKkfjOYC1aRvAZuhpJOb5cu4IBTJdsCigUlf2iCOu4ZDQ==", "license": "MIT", "dependencies": { - "@inquirer/core": "^10.2.2", - "@inquirer/external-editor": "^1.0.2", - "@inquirer/type": "^3.0.8" + "@inquirer/core": "^10.3.2", + "@inquirer/external-editor": "^1.0.3", + "@inquirer/type": "^3.0.10" }, "engines": { "node": ">=18" @@ -1536,14 +954,14 @@ } }, "node_modules/@inquirer/expand": { - "version": "4.0.15", - "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.15.tgz", - "integrity": "sha512-4Y+pbr/U9Qcvf+N/goHzPEXiHH8680lM3Dr3Y9h9FFw4gHS+zVpbj8LfbKWIb/jayIB4aSO4pWiBTrBYWkvi5A==", + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/expand/-/expand-4.0.23.tgz", + "integrity": "sha512-nRzdOyFYnpeYTTR2qFwEVmIWypzdAx/sIkCMeTNTcflFOovfqUk+HcFhQQVBftAh9gmGrpFj6QcGEqrDMDOiew==", "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/type": "^3.0.7", - "yoctocolors-cjs": "^2.1.2" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { "node": ">=18" @@ -1558,12 +976,12 @@ } }, "node_modules/@inquirer/external-editor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.2.tgz", - "integrity": "sha512-yy9cOoBnx58TlsPrIxauKIFQTiyH+0MK4e97y4sV9ERbI+zDxw7i2hxHLCIEGIE/8PPvDxGhgzIOTSOWcs6/MQ==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@inquirer/external-editor/-/external-editor-1.0.3.tgz", + "integrity": "sha512-RWbSrDiYmO4LbejWY7ttpxczuwQyZLBUyygsA9Nsv95hpzUWwnNTVQmAq3xuh7vNwCp07UTmE5i11XAEExx4RA==", "license": "MIT", "dependencies": { - "chardet": "^2.1.0", + "chardet": "^2.1.1", "iconv-lite": "^0.7.0" }, "engines": { @@ -1578,39 +996,23 @@ } } }, - "node_modules/@inquirer/external-editor/node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, "node_modules/@inquirer/figures": { - "version": "1.0.13", - "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.13.tgz", - "integrity": "sha512-lGPVU3yO9ZNqA7vTYz26jny41lE7yoQansmqdMLBEfqaGsmdg7V3W9mK9Pvb5IL4EVZ9GnSDGMO/cJXud5dMaw==", + "version": "1.0.15", + "resolved": "https://registry.npmjs.org/@inquirer/figures/-/figures-1.0.15.tgz", + "integrity": "sha512-t2IEY+unGHOzAaVM5Xx6DEWKeXlDDcNPeDyUpsRc6CUhBfU3VQOEl+Vssh7VNp1dR8MdUJBWhuObjXCsVpjN5g==", "license": "MIT", "engines": { "node": ">=18" } }, "node_modules/@inquirer/input": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.1.12.tgz", - "integrity": "sha512-xJ6PFZpDjC+tC1P8ImGprgcsrzQRsUh9aH3IZixm1lAZFK49UGHxM3ltFfuInN2kPYNfyoPRh+tU4ftsjPLKqQ==", + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/@inquirer/input/-/input-4.3.1.tgz", + "integrity": "sha512-kN0pAM4yPrLjJ1XJBjDxyfDduXOuQHrBB8aLDMueuwUGn+vNpF7Gq7TvyVxx8u4SHlFFj4trmj+a2cbpG4Jn1g==", "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/type": "^3.0.7" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { "node": ">=18" @@ -1625,13 +1027,13 @@ } }, "node_modules/@inquirer/number": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.15.tgz", - "integrity": "sha512-xWg+iYfqdhRiM55MvqiTCleHzszpoigUpN5+t1OMcRkJrUrw7va3AzXaxvS+Ak7Gny0j2mFSTv2JJj8sMtbV2g==", + "version": "3.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/number/-/number-3.0.23.tgz", + "integrity": "sha512-5Smv0OK7K0KUzUfYUXDXQc9jrf8OHo4ktlEayFlelCjwMXz0299Y8OrI+lj7i4gCBY15UObk76q0QtxjzFcFcg==", "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/type": "^3.0.7" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { "node": ">=18" @@ -1646,14 +1048,14 @@ } }, "node_modules/@inquirer/password": { - "version": "4.0.15", - "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.15.tgz", - "integrity": "sha512-75CT2p43DGEnfGTaqFpbDC2p2EEMrq0S+IRrf9iJvYreMy5mAWj087+mdKyLHapUEPLjN10mNvABpGbk8Wdraw==", + "version": "4.0.23", + "resolved": "https://registry.npmjs.org/@inquirer/password/-/password-4.0.23.tgz", + "integrity": "sha512-zREJHjhT5vJBMZX/IUbyI9zVtVfOLiTO66MrF/3GFZYZ7T4YILW5MSkEYHceSii/KtRk+4i3RE7E1CUXA2jHcA==", "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/type": "^3.0.7", - "ansi-escapes": "^4.3.2" + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10" }, "engines": { "node": ">=18" @@ -1668,21 +1070,21 @@ } }, "node_modules/@inquirer/prompts": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.5.3.tgz", - "integrity": "sha512-8YL0WiV7J86hVAxrh3fE5mDCzcTDe1670unmJRz6ArDgN+DBK1a0+rbnNWp4DUB5rPMwqD5ZP6YHl9KK1mbZRg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@inquirer/prompts/-/prompts-7.10.1.tgz", + "integrity": "sha512-Dx/y9bCQcXLI5ooQ5KyvA4FTgeo2jYj/7plWfV5Ak5wDPKQZgudKez2ixyfz7tKXzcJciTxqLeK7R9HItwiByg==", "license": "MIT", "dependencies": { - "@inquirer/checkbox": "^4.1.8", - "@inquirer/confirm": "^5.1.12", - "@inquirer/editor": "^4.2.13", - "@inquirer/expand": "^4.0.15", - "@inquirer/input": "^4.1.12", - "@inquirer/number": "^3.0.15", - "@inquirer/password": "^4.0.15", - "@inquirer/rawlist": "^4.1.3", - "@inquirer/search": "^3.0.15", - "@inquirer/select": "^4.2.3" + "@inquirer/checkbox": "^4.3.2", + "@inquirer/confirm": "^5.1.21", + "@inquirer/editor": "^4.2.23", + "@inquirer/expand": "^4.0.23", + "@inquirer/input": "^4.3.1", + "@inquirer/number": "^3.0.23", + "@inquirer/password": "^4.0.23", + "@inquirer/rawlist": "^4.1.11", + "@inquirer/search": "^3.2.2", + "@inquirer/select": "^4.4.2" }, "engines": { "node": ">=18" @@ -1697,14 +1099,14 @@ } }, "node_modules/@inquirer/rawlist": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.3.tgz", - "integrity": "sha512-7XrV//6kwYumNDSsvJIPeAqa8+p7GJh7H5kRuxirct2cgOcSWwwNGoXDRgpNFbY/MG2vQ4ccIWCi8+IXXyFMZA==", + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/@inquirer/rawlist/-/rawlist-4.1.11.tgz", + "integrity": "sha512-+LLQB8XGr3I5LZN/GuAHo+GpDJegQwuPARLChlMICNdwW7OwV2izlCSCxN6cqpL0sMXmbKbFcItJgdQq5EBXTw==", "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/type": "^3.0.7", - "yoctocolors-cjs": "^2.1.2" + "@inquirer/core": "^10.3.2", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { "node": ">=18" @@ -1719,15 +1121,15 @@ } }, "node_modules/@inquirer/search": { - "version": "3.0.15", - "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.0.15.tgz", - "integrity": "sha512-YBMwPxYBrADqyvP4nNItpwkBnGGglAvCLVW8u4pRmmvOsHUtCAUIMbUrLX5B3tFL1/WsLGdQ2HNzkqswMs5Uaw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@inquirer/search/-/search-3.2.2.tgz", + "integrity": "sha512-p2bvRfENXCZdWF/U2BXvnSI9h+tuA8iNqtUKb9UWbmLYCRQxd8WkvwWvYn+3NgYaNwdUkHytJMGG4MMLucI1kA==", "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/figures": "^1.0.12", - "@inquirer/type": "^3.0.7", - "yoctocolors-cjs": "^2.1.2" + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { "node": ">=18" @@ -1742,16 +1144,16 @@ } }, "node_modules/@inquirer/select": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.2.3.tgz", - "integrity": "sha512-OAGhXU0Cvh0PhLz9xTF/kx6g6x+sP+PcyTiLvCrewI99P3BBeexD+VbuwkNDvqGkk3y2h5ZiWLeRP7BFlhkUDg==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@inquirer/select/-/select-4.4.2.tgz", + "integrity": "sha512-l4xMuJo55MAe+N7Qr4rX90vypFwCajSakx59qe/tMaC1aEHWLyw68wF4o0A4SLAY4E0nd+Vt+EyskeDIqu1M6w==", "license": "MIT", "dependencies": { - "@inquirer/core": "^10.1.13", - "@inquirer/figures": "^1.0.12", - "@inquirer/type": "^3.0.7", - "ansi-escapes": "^4.3.2", - "yoctocolors-cjs": "^2.1.2" + "@inquirer/ansi": "^1.0.2", + "@inquirer/core": "^10.3.2", + "@inquirer/figures": "^1.0.15", + "@inquirer/type": "^3.0.10", + "yoctocolors-cjs": "^2.1.3" }, "engines": { "node": ">=18" @@ -1766,9 +1168,9 @@ } }, "node_modules/@inquirer/type": { - "version": "3.0.8", - "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.8.tgz", - "integrity": "sha512-lg9Whz8onIHRthWaN1Q9EGLa/0LFJjyM8mEUbL1eTi6yMGvBf8gvyDLtxSXztQsxMvhxxNpJYrwa1YHdq+w4Jw==", + "version": "3.0.10", + "resolved": "https://registry.npmjs.org/@inquirer/type/-/type-3.0.10.tgz", + "integrity": "sha512-BvziSRxfz5Ov8ch0z/n3oijRSEcEsHnhggm4xFZe93DHcUCTlutlq9Ox4SVENAfcRD22UQq7T/atg9Wr3k09eA==", "license": "MIT", "engines": { "node": ">=18" @@ -1813,9 +1215,9 @@ } }, "node_modules/@mongodb-js/saslprep": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.3.0.tgz", - "integrity": "sha512-zlayKCsIjYb7/IdfqxorK5+xUMyi4vOKcFy10wKJYc63NSdKI8mNME+uJqfatkPmOSMMUiojrL58IePKBm3gvQ==", + "version": "1.4.12", + "resolved": "https://registry.npmjs.org/@mongodb-js/saslprep/-/saslprep-1.4.12.tgz", + "integrity": "sha512-QAfAMwNgnYxZ2C6D1HgeP7Gc4i/uvJRim415PCIL9ptRxWMNbWeLBYb2/9R4pGKny/s1FVu2JA2cxCUBUOggrA==", "license": "MIT", "optional": true, "dependencies": { @@ -1823,15 +1225,22 @@ } }, "node_modules/@napi-rs/wasm-runtime": { - "version": "0.2.11", - "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.11.tgz", - "integrity": "sha512-9DPkXtvHydrcOsopiYpUgPHpmj0HWZKMUnL2dZqpvC42lsratuBG06V5ipyno0fUek5VlFsNQ+AcFATSrJXgMA==", + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.6.tgz", + "integrity": "sha512-ZLv/JdUfkvOy9eCnnBaGfiO+XimbjebAeO+MRQqD/B+FR1tnRN0tpKSJHRbE8sFfS6aqsXZ67TQjfwfsxULVbg==", + "dev": true, "license": "MIT", "optional": true, "dependencies": { - "@emnapi/core": "^1.4.3", - "@emnapi/runtime": "^1.4.3", - "@tybys/wasm-util": "^0.9.0" + "@tybys/wasm-util": "^0.10.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Brooooooklyn" + }, + "peerDependencies": { + "@emnapi/core": "^1.7.1", + "@emnapi/runtime": "^1.7.1" } }, "node_modules/@node-rs/crc32": { @@ -2039,6 +1448,18 @@ "node": ">=14.0.0" } }, + "node_modules/@node-rs/crc32-wasm32-wasi/node_modules/@napi-rs/wasm-runtime": { + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-0.2.12.tgz", + "integrity": "sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==", + "license": "MIT", + "optional": true, + "dependencies": { + "@emnapi/core": "^1.4.3", + "@emnapi/runtime": "^1.4.3", + "@tybys/wasm-util": "^0.10.0" + } + }, "node_modules/@node-rs/crc32-win32-arm64-msvc": { "version": "1.10.6", "resolved": "https://registry.npmjs.org/@node-rs/crc32-win32-arm64-msvc/-/crc32-win32-arm64-msvc-1.10.6.tgz", @@ -2087,54 +1508,6 @@ "node": ">= 10" } }, - "node_modules/@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@nolyfill/is-core-module": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/@nolyfill/is-core-module/-/is-core-module-1.0.39.tgz", - "integrity": "sha512-nn5ozdjYQpUCZlWGuxcJY/KpxkWQs4DcbMCmKojjyrYDEAGy4Ce19NN4v5MduafTwJlbKc99UA8YhSVqq9yPZA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=12.4.0" - } - }, "node_modules/@oozcitak/dom": { "version": "0.0.11", "resolved": "https://registry.npmjs.org/@oozcitak/dom/-/dom-0.0.11.tgz", @@ -2264,27 +1637,41 @@ } }, "node_modules/@pretendonetwork/eslint-config": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/@pretendonetwork/eslint-config/-/eslint-config-0.0.8.tgz", - "integrity": "sha512-UH4f+Ya14l6hXS8CHd+SaTk9w0o8h4UT+igbRkZ7DdW0h6YqfM1xe3K9Oqsb1zouLUrYlDVAzBXKJFTwG6kyzg==", + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/@pretendonetwork/eslint-config/-/eslint-config-0.1.4.tgz", + "integrity": "sha512-3Y6PvfAOLBLMstWUwbuAP/Qfiq0KitAvKpYFWCR6aSel60wxHEJpPAB92rGSXep6LRaZw2qlLbGcLrHn12onsA==", "dev": true, "dependencies": { - "@eslint-community/eslint-plugin-eslint-comments": "^4.4.1", - "@stylistic/eslint-plugin": "^2.12.1", - "eslint": "^9.17.0", - "eslint-import-resolver-typescript": "^3.7.0", - "eslint-plugin-import": "^2.31.0", - "globals": "^15.14.0", - "typescript-eslint": "^8.19.1" + "@eslint-community/eslint-plugin-eslint-comments": "^4.6.0", + "@stylistic/eslint-plugin": "^5.9.0", + "eslint": "^9.39.3", + "eslint-import-resolver-typescript": "^4.4.4", + "eslint-plugin-import": "^2.32.0", + "eslint-plugin-react": "^7.37.5", + "globals": "^17.4.0", + "typescript-eslint": "^8.56.1" }, "peerDependencies": { "@typescript-eslint/parser": "^8.20.0" } }, + "node_modules/@pretendonetwork/eslint-config/node_modules/globals": { + "version": "17.7.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-17.7.0.tgz", + "integrity": "sha512-Czmyns5dUsq4seFBR/Kdydhmo8y9kC79hiSkPn0YcGtNnYWnrgt0vjrSjx9tspoDGWm2CMarffRuLjM4xUz8xg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/@pretendonetwork/grpc": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/@pretendonetwork/grpc/-/grpc-2.2.3.tgz", - "integrity": "sha512-bTyUtFPT1/IwAWix9nkNZlmUUlG/k0F6YnARpNIceg9F6Mw1iHvGvMwvuX06PY9svnKDUeGdyR41rl/YUilfBQ==", + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/@pretendonetwork/grpc/-/grpc-2.5.4.tgz", + "integrity": "sha512-spjg6sOSP8z+9T9vqR9RM5guJb7UHYQlFBfb6p6WxpaYHsXlmVIRPeQlR7NTkgpNzARV/4QVpqerBbtLDvN4oA==", "license": "AGPL-3.0-only", "dependencies": { "@bufbuild/protobuf": "^2.2.2", @@ -2293,9 +1680,9 @@ } }, "node_modules/@pretendonetwork/grpc/node_modules/typescript": { - "version": "5.8.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz", - "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", @@ -2318,25 +1705,24 @@ "license": "BSD-3-Clause" }, "node_modules/@protobufjs/codegen": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", - "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.5.tgz", + "integrity": "sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/eventemitter": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", - "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.1.tgz", + "integrity": "sha512-vW1GmwMZNnL+gMRaovlh9yZX74kc+TTU3FObkkurpMaRtBfLP3ldjS9KQWlwZgraRE0+dheEEoAxdzcJQ8eXZg==", "license": "BSD-3-Clause" }, "node_modules/@protobufjs/fetch": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", - "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.1.tgz", + "integrity": "sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==", "license": "BSD-3-Clause", "dependencies": { - "@protobufjs/aspromise": "^1.1.1", - "@protobufjs/inquire": "^1.1.0" + "@protobufjs/aspromise": "^1.1.1" } }, "node_modules/@protobufjs/float": { @@ -2345,12 +1731,6 @@ "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", "license": "BSD-3-Clause" }, - "node_modules/@protobufjs/inquire": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", - "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", - "license": "BSD-3-Clause" - }, "node_modules/@protobufjs/path": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", @@ -2364,9 +1744,9 @@ "license": "BSD-3-Clause" }, "node_modules/@protobufjs/utf8": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", - "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.2.tgz", + "integrity": "sha512-b1UQwcEZ4yCnMCD8DAL1VlbvBJE9/IX4FTIp7BG1xYpf29SLazLSrqUkj4w7Y5y7cCVP6E5tcqqcI0xemPkHug==", "license": "BSD-3-Clause" }, "node_modules/@redis/bloom": { @@ -2383,7 +1763,6 @@ "resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.1.tgz", "integrity": "sha512-/KCsg3xSlR+nCK8/8ZYSknYxvXHwubJrU82F3Lm1Fp6789VQ0/3RJKfsmRXjqfaTA++23CvC3hqmqe/2GEt6Kw==", "license": "MIT", - "peer": true, "dependencies": { "cluster-key-slot": "1.1.2", "generic-pool": "3.9.0", @@ -2436,27 +1815,6 @@ "dev": true, "license": "MIT" }, - "node_modules/@sideway/address": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@sideway/address/-/address-4.1.5.tgz", - "integrity": "sha512-IqO/DUQHUkPeixNQ8n0JA6102hT9CmaljNTPmQ1u8MEhBo/R4Q8eKLN/vGZxuebwOroDB4cbpjheD4+/sKFK4Q==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.0.0" - } - }, - "node_modules/@sideway/formula": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz", - "integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==", - "license": "BSD-3-Clause" - }, - "node_modules/@sideway/pinpoint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@sideway/pinpoint/-/pinpoint-2.0.0.tgz", - "integrity": "sha512-RNiOoTPkptFtSVzQevY/yWtZwf/RxyVnPy/OcA9HBM3MlGDnBEYL5B41H0MTn0Uec8Hi+2qUtTfG2WWZBmMejQ==", - "license": "BSD-3-Clause" - }, "node_modules/@sindresorhus/is": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", @@ -2469,74 +1827,13 @@ "url": "https://github.com/sindresorhus/is?sponsor=1" } }, - "node_modules/@smithy/abort-controller": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-4.0.4.tgz", - "integrity": "sha512-gJnEjZMvigPDQWHrW3oPrFhQtkrgqBkyjj3pCIdF3A5M6vsZODG93KNlfJprv6bp4245bdT32fsHK4kkH3KYDA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/chunked-blob-reader": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader/-/chunked-blob-reader-5.0.0.tgz", - "integrity": "sha512-+sKqDBQqb036hh4NPaUiEkYFkTUGYzRsn3EuFhyfQfMy6oGHEUJDurLP9Ufb5dasr/XiAmPNMr6wa9afjQB+Gw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/chunked-blob-reader-native": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/chunked-blob-reader-native/-/chunked-blob-reader-native-4.0.0.tgz", - "integrity": "sha512-R9wM2yPmfEMsUmlMlIgSzOyICs0x9uu7UTHoccMyt7BWw8shcGM8HqB355+BZCPBcySvbTYMs62EgEQkNxz2ig==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-base64": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/config-resolver": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-4.1.4.tgz", - "integrity": "sha512-prmU+rDddxHOH0oNcwemL+SwnzcG65sBF2yXRO7aeXIn/xTlq2pX7JLVbkBnVLowHLg4/OL4+jBmv9hVrVGS+w==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^4.1.3", - "@smithy/types": "^4.3.1", - "@smithy/util-config-provider": "^4.0.0", - "@smithy/util-middleware": "^4.0.4", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@smithy/core": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.5.3.tgz", - "integrity": "sha512-xa5byV9fEguZNofCclv6v9ra0FYh5FATQW/da7FQUVTic94DfrN/NvmKZjrMyzbpqfot9ZjBaO8U1UeTbmSLuA==", + "version": "3.29.4", + "resolved": "https://registry.npmjs.org/@smithy/core/-/core-3.29.4.tgz", + "integrity": "sha512-G1GRglAabzEhqghJMBAd54FkRS7SAFGHEwbhcI9r+O+LIMuFsLyXkLZkCoFSgAglRu8s/URVXJB0hglq3ZipIg==", "license": "Apache-2.0", "dependencies": { - "@smithy/middleware-serde": "^4.0.8", - "@smithy/protocol-http": "^5.1.2", - "@smithy/types": "^4.3.1", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-body-length-browser": "^4.0.0", - "@smithy/util-middleware": "^4.0.4", - "@smithy/util-stream": "^4.2.2", - "@smithy/util-utf8": "^4.0.0", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -2544,85 +1841,13 @@ } }, "node_modules/@smithy/credential-provider-imds": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.0.6.tgz", - "integrity": "sha512-hKMWcANhUiNbCJouYkZ9V3+/Qf9pteR1dnwgdyzR09R4ODEYx8BbUysHwRSyex4rZ9zapddZhLFTnT4ZijR4pw==", + "version": "4.4.9", + "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-4.4.9.tgz", + "integrity": "sha512-2nfV4qRKiYeXU4zD2vvSCfg5dfp/BuhrM73vt7q9gzBhxs4rbPxXY21wo+kyI3bRmXcEGRnCLTaW8O437jzHIg==", "license": "Apache-2.0", "dependencies": { - "@smithy/node-config-provider": "^4.1.3", - "@smithy/property-provider": "^4.0.4", - "@smithy/types": "^4.3.1", - "@smithy/url-parser": "^4.0.4", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/eventstream-codec": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-4.0.4.tgz", - "integrity": "sha512-7XoWfZqWb/QoR/rAU4VSi0mWnO2vu9/ltS6JZ5ZSZv0eovLVfDfu0/AX4ub33RsJTOth3TiFWSHS5YdztvFnig==", - "license": "Apache-2.0", - "dependencies": { - "@aws-crypto/crc32": "5.2.0", - "@smithy/types": "^4.3.1", - "@smithy/util-hex-encoding": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-browser": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-4.0.4.tgz", - "integrity": "sha512-3fb/9SYaYqbpy/z/H3yIi0bYKyAa89y6xPmIqwr2vQiUT2St+avRt8UKwsWt9fEdEasc5d/V+QjrviRaX1JRFA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/eventstream-serde-universal": "^4.0.4", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-config-resolver": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-4.1.2.tgz", - "integrity": "sha512-JGtambizrWP50xHgbzZI04IWU7LdI0nh/wGbqH3sJesYToMi2j/DcoElqyOcqEIG/D4tNyxgRuaqBXWE3zOFhQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-node": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-4.0.4.tgz", - "integrity": "sha512-RD6UwNZ5zISpOWPuhVgRz60GkSIp0dy1fuZmj4RYmqLVRtejFqQ16WmfYDdoSoAjlp1LX+FnZo+/hkdmyyGZ1w==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/eventstream-serde-universal": "^4.0.4", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/eventstream-serde-universal": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-4.0.4.tgz", - "integrity": "sha512-UeJpOmLGhq1SLox79QWw/0n2PFX+oPRE1ZyRMxPIaFEfCqWaqpB7BU9C8kpPOGEhLF7AwEqfFbtwNxGy4ReENA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/eventstream-codec": "^4.0.4", - "@smithy/types": "^4.3.1", + "@smithy/core": "^3.29.4", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -2630,193 +1855,13 @@ } }, "node_modules/@smithy/fetch-http-handler": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.0.4.tgz", - "integrity": "sha512-AMtBR5pHppYMVD7z7G+OlHHAcgAN7v0kVKEpHuTO4Gb199Gowh0taYi9oDStFeUhetkeP55JLSVlTW1n9rFtUw==", + "version": "5.6.6", + "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-5.6.6.tgz", + "integrity": "sha512-NHLgAlORUFZjn5ZfhYuyyKMlXA1WLYOdGxEhyNxrPpbJzoacGbl0chn1lN2KiZ8mpNVk0tV5607CSYlYs/OFgw==", "license": "Apache-2.0", "dependencies": { - "@smithy/protocol-http": "^5.1.2", - "@smithy/querystring-builder": "^4.0.4", - "@smithy/types": "^4.3.1", - "@smithy/util-base64": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/hash-blob-browser": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/hash-blob-browser/-/hash-blob-browser-4.0.4.tgz", - "integrity": "sha512-WszRiACJiQV3QG6XMV44i5YWlkrlsM5Yxgz4jvsksuu7LDXA6wAtypfPajtNTadzpJy3KyJPoWehYpmZGKUFIQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/chunked-blob-reader": "^5.0.0", - "@smithy/chunked-blob-reader-native": "^4.0.0", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/hash-node": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-4.0.4.tgz", - "integrity": "sha512-qnbTPUhCVnCgBp4z4BUJUhOEkVwxiEi1cyFM+Zj6o+aY8OFGxUQleKWq8ltgp3dujuhXojIvJWdoqpm6dVO3lQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.1", - "@smithy/util-buffer-from": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/hash-stream-node": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/hash-stream-node/-/hash-stream-node-4.0.4.tgz", - "integrity": "sha512-wHo0d8GXyVmpmMh/qOR0R7Y46/G1y6OR8U+bSTB4ppEzRxd1xVAQ9xOE9hOc0bSjhz0ujCPAbfNLkLrpa6cevg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.1", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/invalid-dependency": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-4.0.4.tgz", - "integrity": "sha512-bNYMi7WKTJHu0gn26wg8OscncTt1t2b8KcsZxvOv56XA6cyXtOAAAaNP7+m45xfppXfOatXF3Sb1MNsLUgVLTw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/is-array-buffer": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-4.0.0.tgz", - "integrity": "sha512-saYhF8ZZNoJDTvJBEWgeBccCg+yvp1CX+ed12yORU3NilJScfc6gfch2oVb4QgxZrGUx3/ZJlb+c/dJbyupxlw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/md5-js": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/md5-js/-/md5-js-4.0.4.tgz", - "integrity": "sha512-uGLBVqcOwrLvGh/v/jw423yWHq/ofUGK1W31M2TNspLQbUV1Va0F5kTxtirkoHawODAZcjXTSGi7JwbnPcDPJg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.1", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/middleware-content-length": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-4.0.4.tgz", - "integrity": "sha512-F7gDyfI2BB1Kc+4M6rpuOLne5LOcEknH1n6UQB69qv+HucXBR1rkzXBnQTB2q46sFy1PM/zuSJOB532yc8bg3w==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/protocol-http": "^5.1.2", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/middleware-endpoint": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-4.1.11.tgz", - "integrity": "sha512-zDogwtRLzKl58lVS8wPcARevFZNBOOqnmzWWxVe9XiaXU2CADFjvJ9XfNibgkOWs08sxLuSr81NrpY4mgp9OwQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.5.3", - "@smithy/middleware-serde": "^4.0.8", - "@smithy/node-config-provider": "^4.1.3", - "@smithy/shared-ini-file-loader": "^4.0.4", - "@smithy/types": "^4.3.1", - "@smithy/url-parser": "^4.0.4", - "@smithy/util-middleware": "^4.0.4", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/middleware-retry": { - "version": "4.1.12", - "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-4.1.12.tgz", - "integrity": "sha512-wvIH70c4e91NtRxdaLZF+mbLZ/HcC6yg7ySKUiufL6ESp6zJUSnJucZ309AvG9nqCFHSRB5I6T3Ez1Q9wCh0Ww==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^4.1.3", - "@smithy/protocol-http": "^5.1.2", - "@smithy/service-error-classification": "^4.0.5", - "@smithy/smithy-client": "^4.4.3", - "@smithy/types": "^4.3.1", - "@smithy/util-middleware": "^4.0.4", - "@smithy/util-retry": "^4.0.5", - "tslib": "^2.6.2", - "uuid": "^9.0.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/middleware-serde": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-4.0.8.tgz", - "integrity": "sha512-iSSl7HJoJaGyMIoNn2B7czghOVwJ9nD7TMvLhMWeSB5vt0TnEYyRRqPJu/TqW76WScaNvYYB8nRoiBHR9S1Ddw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/protocol-http": "^5.1.2", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/middleware-stack": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-4.0.4.tgz", - "integrity": "sha512-kagK5ggDrBUCCzI93ft6DjteNSfY8Ulr83UtySog/h09lTIOAJ/xUSObutanlPT0nhoHAkpmW9V5K8oPyLh+QA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/node-config-provider": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-4.1.3.tgz", - "integrity": "sha512-HGHQr2s59qaU1lrVH6MbLlmOBxadtzTsoO4c+bF5asdgVik3I8o7JIOzoeqWc5MjVa+vD36/LWE0iXKpNqooRw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/property-provider": "^4.0.4", - "@smithy/shared-ini-file-loader": "^4.0.4", - "@smithy/types": "^4.3.1", + "@smithy/core": "^3.29.4", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -2824,93 +1869,13 @@ } }, "node_modules/@smithy/node-http-handler": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.0.6.tgz", - "integrity": "sha512-NqbmSz7AW2rvw4kXhKGrYTiJVDHnMsFnX4i+/FzcZAfbOBauPYs2ekuECkSbtqaxETLLTu9Rl/ex6+I2BKErPA==", + "version": "4.9.6", + "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-4.9.6.tgz", + "integrity": "sha512-odd+HYx3OLcXRSEz0ZeF3JQdSYdK8QnRgA2N87cPW7coWIbKfRk7a9VQjfeWQLqnzrDLk23KMEn46p8N7M/JFg==", "license": "Apache-2.0", "dependencies": { - "@smithy/abort-controller": "^4.0.4", - "@smithy/protocol-http": "^5.1.2", - "@smithy/querystring-builder": "^4.0.4", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/property-provider": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-4.0.4.tgz", - "integrity": "sha512-qHJ2sSgu4FqF4U/5UUp4DhXNmdTrgmoAai6oQiM+c5RZ/sbDwJ12qxB1M6FnP+Tn/ggkPZf9ccn4jqKSINaquw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/protocol-http": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-5.1.2.tgz", - "integrity": "sha512-rOG5cNLBXovxIrICSBm95dLqzfvxjEmuZx4KK3hWwPFHGdW3lxY0fZNXfv2zebfRO7sJZ5pKJYHScsqopeIWtQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/querystring-builder": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-4.0.4.tgz", - "integrity": "sha512-SwREZcDnEYoh9tLNgMbpop+UTGq44Hl9tdj3rf+yeLcfH7+J8OXEBaMc2kDxtyRHu8BhSg9ADEx0gFHvpJgU8w==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.1", - "@smithy/util-uri-escape": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/querystring-parser": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-4.0.4.tgz", - "integrity": "sha512-6yZf53i/qB8gRHH/l2ZwUG5xgkPgQF15/KxH0DdXMDHjesA9MeZje/853ifkSY0x4m5S+dfDZ+c4x439PF0M2w==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/service-error-classification": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-4.0.5.tgz", - "integrity": "sha512-LvcfhrnCBvCmTee81pRlh1F39yTS/+kYleVeLCwNtkY8wtGg8V/ca9rbZZvYIl8OjlMtL6KIjaiL/lgVqHD2nA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.1" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/shared-ini-file-loader": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-4.0.4.tgz", - "integrity": "sha512-63X0260LoFBjrHifPDs+nM9tV0VMkOTl4JRMYNuKh/f5PauSjowTfvF3LogfkWdcPoxsA9UjqEOgjeYIbhb7Nw==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.1", + "@smithy/core": "^3.29.4", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -2918,36 +1883,13 @@ } }, "node_modules/@smithy/signature-v4": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.1.2.tgz", - "integrity": "sha512-d3+U/VpX7a60seHziWnVZOHuEgJlclufjkS6zhXvxcJgkJq4UWdH5eOBLzHRMx6gXjsdT9h6lfpmLzbrdupHgQ==", + "version": "5.6.5", + "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-5.6.5.tgz", + "integrity": "sha512-MO5VEhwVl0BN7xVoVeNrZfiUFoQtqxUbgl6/RwOTlMMxCSjblG8twSrVTwz3J4w9WZxd2rBfBAUXjH77agspBg==", "license": "Apache-2.0", "dependencies": { - "@smithy/is-array-buffer": "^4.0.0", - "@smithy/protocol-http": "^5.1.2", - "@smithy/types": "^4.3.1", - "@smithy/util-hex-encoding": "^4.0.0", - "@smithy/util-middleware": "^4.0.4", - "@smithy/util-uri-escape": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/smithy-client": { - "version": "4.4.3", - "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-4.4.3.tgz", - "integrity": "sha512-xxzNYgA0HD6ETCe5QJubsxP0hQH3QK3kbpJz3QrosBCuIWyEXLR/CO5hFb2OeawEKUxMNhz3a1nuJNN2np2RMA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/core": "^3.5.3", - "@smithy/middleware-endpoint": "^4.1.11", - "@smithy/middleware-stack": "^4.0.4", - "@smithy/protocol-http": "^5.1.2", - "@smithy/types": "^4.3.1", - "@smithy/util-stream": "^4.2.2", + "@smithy/core": "^3.29.4", + "@smithy/types": "^4.16.1", "tslib": "^2.6.2" }, "engines": { @@ -2955,9 +1897,9 @@ } }, "node_modules/@smithy/types": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.3.1.tgz", - "integrity": "sha512-UqKOQBL2x6+HWl3P+3QqFD4ncKq0I8Nuz9QItGv5WuKuMHuuwlhvqcZCoXGfc+P1QmfJE7VieykoYYmrOoFJxA==", + "version": "4.16.1", + "resolved": "https://registry.npmjs.org/@smithy/types/-/types-4.16.1.tgz", + "integrity": "sha512-0JFs3V2y2M9tKW5na/qxe69Zv+uxLMO7QBbhxF/FHu/Gp2NFZAAL9tWl9PU02xxo07pb3G9FTyjNc6D5uZrJIg==", "license": "Apache-2.0", "dependencies": { "tslib": "^2.6.2" @@ -2966,246 +1908,25 @@ "node": ">=18.0.0" } }, - "node_modules/@smithy/url-parser": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-4.0.4.tgz", - "integrity": "sha512-eMkc144MuN7B0TDA4U2fKs+BqczVbk3W+qIvcoCY6D1JY3hnAdCuhCZODC+GAeaxj0p6Jroz4+XMUn3PCxQQeQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/querystring-parser": "^4.0.4", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-base64": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-4.0.0.tgz", - "integrity": "sha512-CvHfCmO2mchox9kjrtzoHkWHxjHZzaFojLc8quxXY7WAAMAg43nuxwv95tATVgQFNDwd4M9S1qFzj40Ul41Kmg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-body-length-browser": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-4.0.0.tgz", - "integrity": "sha512-sNi3DL0/k64/LO3A256M+m3CDdG6V7WKWHdAiBBMUN8S3hK3aMPhwnPik2A/a2ONN+9doY9UxaLfgqsIRg69QA==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-body-length-node": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-4.0.0.tgz", - "integrity": "sha512-q0iDP3VsZzqJyje8xJWEJCNIu3lktUGVoSy1KB0UWym2CL1siV3artm+u1DFYTLejpsrdGyCSWBdGNjJzfDPjg==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-buffer-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-4.0.0.tgz", - "integrity": "sha512-9TOQ7781sZvddgO8nxueKi3+yGvkY35kotA0Y6BWRajAv8jjmigQ1sBwz0UX47pQMYXJPahSKEKYFgt+rXdcug==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/is-array-buffer": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-config-provider": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-4.0.0.tgz", - "integrity": "sha512-L1RBVzLyfE8OXH+1hsJ8p+acNUSirQnWQ6/EgpchV88G6zGBTDPdXiiExei6Z1wR2RxYvxY/XLw6AMNCCt8H3w==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-browser": { - "version": "4.0.19", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-4.0.19.tgz", - "integrity": "sha512-mvLMh87xSmQrV5XqnUYEPoiFFeEGYeAKIDDKdhE2ahqitm8OHM3aSvhqL6rrK6wm1brIk90JhxDf5lf2hbrLbQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/property-provider": "^4.0.4", - "@smithy/smithy-client": "^4.4.3", - "@smithy/types": "^4.3.1", - "bowser": "^2.11.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-defaults-mode-node": { - "version": "4.0.19", - "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-4.0.19.tgz", - "integrity": "sha512-8tYnx+LUfj6m+zkUUIrIQJxPM1xVxfRBvoGHua7R/i6qAxOMjqR6CpEpDwKoIs1o0+hOjGvkKE23CafKL0vJ9w==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/config-resolver": "^4.1.4", - "@smithy/credential-provider-imds": "^4.0.6", - "@smithy/node-config-provider": "^4.1.3", - "@smithy/property-provider": "^4.0.4", - "@smithy/smithy-client": "^4.4.3", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-endpoints": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-3.0.6.tgz", - "integrity": "sha512-YARl3tFL3WgPuLzljRUnrS2ngLiUtkwhQtj8PAL13XZSyUiNLQxwG3fBBq3QXFqGFUXepIN73pINp3y8c2nBmA==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/node-config-provider": "^4.1.3", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-hex-encoding": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-4.0.0.tgz", - "integrity": "sha512-Yk5mLhHtfIgW2W2WQZWSg5kuMZCVbvhFmC7rV4IO2QqnZdbEFPmQnCcGMAX2z/8Qj3B9hYYNjZOhWym+RwhePw==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-middleware": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-4.0.4.tgz", - "integrity": "sha512-9MLKmkBmf4PRb0ONJikCbCwORACcil6gUWojwARCClT7RmLzF04hUR4WdRprIXal7XVyrddadYNfp2eF3nrvtQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-retry": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-4.0.5.tgz", - "integrity": "sha512-V7MSjVDTlEt/plmOFBn1762Dyu5uqMrV2Pl2X0dYk4XvWfdWJNe9Bs5Bzb56wkCuiWjSfClVMGcsuKrGj7S/yg==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/service-error-classification": "^4.0.5", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-stream": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-4.2.2.tgz", - "integrity": "sha512-aI+GLi7MJoVxg24/3J1ipwLoYzgkB4kUfogZfnslcYlynj3xsQ0e7vk4TnTro9hhsS5PvX1mwmkRqqHQjwcU7w==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/fetch-http-handler": "^5.0.4", - "@smithy/node-http-handler": "^4.0.6", - "@smithy/types": "^4.3.1", - "@smithy/util-base64": "^4.0.0", - "@smithy/util-buffer-from": "^4.0.0", - "@smithy/util-hex-encoding": "^4.0.0", - "@smithy/util-utf8": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-uri-escape": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-4.0.0.tgz", - "integrity": "sha512-77yfbCbQMtgtTylO9itEAdpPXSog3ZxMe09AEhm0dU0NLTalV70ghDZFR+Nfi1C60jnJoh/Re4090/DuZh2Omg==", - "license": "Apache-2.0", - "dependencies": { - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-utf8": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-4.0.0.tgz", - "integrity": "sha512-b+zebfKCfRdgNJDknHCob3O7FpeYQN6ZG6YLExMcasDHsCXlsXCEuiPZeLnJLpwa5dvPetGlnGCiMHuLwGvFow==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/util-buffer-from": "^4.0.0", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/@smithy/util-waiter": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-4.0.5.tgz", - "integrity": "sha512-4QvC49HTteI1gfemu0I1syWovJgPvGn7CVUoN9ZFkdvr/cCFkrEL7qNCdx/2eICqDWEGnnr68oMdSIPCLAriSQ==", - "license": "Apache-2.0", - "dependencies": { - "@smithy/abort-controller": "^4.0.4", - "@smithy/types": "^4.3.1", - "tslib": "^2.6.2" - }, - "engines": { - "node": ">=18.0.0" - } - }, "node_modules/@stylistic/eslint-plugin": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-2.13.0.tgz", - "integrity": "sha512-RnO1SaiCFHn666wNz2QfZEFxvmiNRqhzaMXHXxXXKt+MEP7aajlPxUSMIQpKAaJfverpovEYqjBOXDq6dDcaOQ==", + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-5.10.0.tgz", + "integrity": "sha512-nPK52ZHvot8Ju/0A4ucSX1dcPV2/1clx0kLcH5wDmrE4naKso7TUC/voUyU1O9OTKTrR6MYip6LP0ogEMQ9jPQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "^8.13.0", - "eslint-visitor-keys": "^4.2.0", - "espree": "^10.3.0", + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/types": "^8.56.0", + "eslint-visitor-keys": "^4.2.1", + "espree": "^10.4.0", "estraverse": "^5.3.0", - "picomatch": "^4.0.2" + "picomatch": "^4.0.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "peerDependencies": { - "eslint": ">=8.40.0" + "eslint": "^9.0.0 || ^10.0.0" } }, "node_modules/@szmarczak/http-timer": { @@ -3221,9 +1942,9 @@ } }, "node_modules/@tybys/wasm-util": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.9.0.tgz", - "integrity": "sha512-6+7nlbMVX/PVDCwaIQ8nTOPveOcFLSt8GcXdx8hD0bt39uWxYT88uXzqTd4fTvqta7oeUJqudepapKNt2DYJFw==", + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.3.tgz", + "integrity": "sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==", "license": "MIT", "optional": true, "dependencies": { @@ -3304,29 +2025,29 @@ } }, "node_modules/@types/estree": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz", - "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.9.tgz", + "integrity": "sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==", "dev": true, "license": "MIT" }, "node_modules/@types/express": { - "version": "4.17.23", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.23.tgz", - "integrity": "sha512-Crp6WY9aTYP3qPi2wGDo9iUe/rceX01UMhnF1jmwDcKCFM6cx7YhGP/Mpr3y9AASpfHixIG0E6azCcL5OcDHsQ==", + "version": "4.17.25", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.25.tgz", + "integrity": "sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==", "dev": true, "license": "MIT", "dependencies": { "@types/body-parser": "*", "@types/express-serve-static-core": "^4.17.33", "@types/qs": "*", - "@types/serve-static": "*" + "@types/serve-static": "^1" } }, "node_modules/@types/express-serve-static-core": { - "version": "4.19.6", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.6.tgz", - "integrity": "sha512-N4LZ2xG7DatVqhCZzOGb1Yi5lMbXSZcmdLDe9EzSndPV2HpWYWzRbaerl2n27irrm94EPpprqa8KpskPT085+A==", + "version": "4.19.9", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.19.9.tgz", + "integrity": "sha512-QP2ESEe/ImWY0HDwNAnK9PvEffUyhLTnWkk7KXzHfyeWAnlrDe1fN77bXl6ia8KT3wPlmA7t9/VPRpnf4Ex9sg==", "dev": true, "license": "MIT", "dependencies": { @@ -3355,9 +2076,9 @@ "license": "MIT" }, "node_modules/@types/http-cache-semantics": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", - "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.2.0.tgz", + "integrity": "sha512-L3LgimLHXtGkWikKnsPg0/VFx9OGZaC+eN1u4r+OB1XRqH3meBIAVC2zr1WdMH+RHmnRkqliQAOHNJ/E0j/e0Q==", "license": "MIT" }, "node_modules/@types/http-errors": { @@ -3400,6 +2121,12 @@ "@types/node": "*" } }, + "node_modules/@types/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-gW+Oib+vUtGJBtNC8V9Reww0oIpusw+4m81uncg9REGZAJfqOQHfo/nkabnc7w0QReXyPqjrbWMJk6NuAkiX3Q==", + "license": "MIT" + }, "node_modules/@types/mime": { "version": "1.3.5", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.5.tgz", @@ -3425,11 +2152,10 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "18.19.112", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.112.tgz", - "integrity": "sha512-i+Vukt9POdS/MBI7YrrkkI5fMfwFtOjphSmt4WXYLfwqsfr6z/HdCx7LqT9M7JktGob8WNgj8nFB4TbGNE4Cog==", + "version": "18.19.130", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz", + "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==", "license": "MIT", - "peer": true, "dependencies": { "undici-types": "~5.26.4" } @@ -3445,9 +2171,9 @@ } }, "node_modules/@types/nodemailer": { - "version": "6.4.17", - "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.17.tgz", - "integrity": "sha512-I9CCaIp6DTldEg7vyUTZi8+9Vo0hi1/T8gv3C89yk1rSAAzoKQ8H8ki/jBYJSFoH/BisgLP8tkZMlQ91CIquww==", + "version": "6.4.24", + "resolved": "https://registry.npmjs.org/@types/nodemailer/-/nodemailer-6.4.24.tgz", + "integrity": "sha512-Ww4u0rT9wQNXh4JiQaIwx3QWdcOFXzOjQA2zc+jtFYNmQiT4mIUqcDin51bDFdkzKubFnQCZNK7FIHlPKQ/q9w==", "dev": true, "license": "MIT", "dependencies": { @@ -3455,9 +2181,9 @@ } }, "node_modules/@types/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ==", + "version": "6.15.1", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.15.1.tgz", + "integrity": "sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==", "dev": true, "license": "MIT" }, @@ -3478,9 +2204,31 @@ } }, "node_modules/@types/send": { - "version": "0.17.5", - "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.5.tgz", - "integrity": "sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@types/send/-/send-1.2.1.tgz", + "integrity": "sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.15.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.10.tgz", + "integrity": "sha512-tRs1dB+g8Itk72rlSI2ZrW6vZg0YrLI81iQSTkMmOqnqCaNr/8Ek4VwWcN5vZgCYWbg/JJSGBlUaYGAOP73qBw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/http-errors": "*", + "@types/node": "*", + "@types/send": "<1" + } + }, + "node_modules/@types/serve-static/node_modules/@types/send": { + "version": "0.17.6", + "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.6.tgz", + "integrity": "sha512-Uqt8rPBE8SY0RK8JB1EzVOIZ32uqy8HwdxCnoCOsYrvnswqmFZ/k+9Ikidlk/ImhsdvBsloHbAlewb2IEBV/Og==", "dev": true, "license": "MIT", "dependencies": { @@ -3488,28 +2236,10 @@ "@types/node": "*" } }, - "node_modules/@types/serve-static": { - "version": "1.15.8", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.15.8.tgz", - "integrity": "sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/http-errors": "*", - "@types/node": "*", - "@types/send": "*" - } - }, - "node_modules/@types/uuid": { - "version": "9.0.8", - "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", - "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==", - "license": "MIT" - }, "node_modules/@types/validator": { - "version": "13.15.2", - "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.2.tgz", - "integrity": "sha512-y7pa/oEJJ4iGYBxOpfAKn5b9+xuihvzDVnC/OSvlVnGxVg0pOqmjiMafiJ1KVNQEaPZf9HsEp5icEwGg8uIe5Q==", + "version": "13.15.10", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.15.10.tgz", + "integrity": "sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==", "dev": true, "license": "MIT" }, @@ -3530,21 +2260,20 @@ } }, "node_modules/@typescript-eslint/eslint-plugin": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.34.1.tgz", - "integrity": "sha512-STXcN6ebF6li4PxwNeFnqF8/2BNDvBupf2OPx2yWNzr6mKNGF7q49VM00Pz5FaomJyqvbXpY6PhO+T9w139YEQ==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.64.0.tgz", + "integrity": "sha512-CGvQPBxN3wZLu6Rz2kFUpZeoCm78xUic92ck39KPePkO1NPOwjCqdQnm5Q87tpWw9vcBvW8XLrDXjH9PWYtJ3Q==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/regexpp": "^4.10.0", - "@typescript-eslint/scope-manager": "8.34.1", - "@typescript-eslint/type-utils": "8.34.1", - "@typescript-eslint/utils": "8.34.1", - "@typescript-eslint/visitor-keys": "8.34.1", - "graphemer": "^1.4.0", - "ignore": "^7.0.0", + "@eslint-community/regexpp": "^4.12.2", + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/type-utils": "8.64.0", + "@typescript-eslint/utils": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", + "ignore": "^7.0.5", "natural-compare": "^1.4.0", - "ts-api-utils": "^2.1.0" + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3554,34 +2283,23 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^8.34.1", - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" - } - }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": { - "version": "7.0.5", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz", - "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 4" + "@typescript-eslint/parser": "^8.64.0", + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/parser": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.34.1.tgz", - "integrity": "sha512-4O3idHxhyzjClSMJ0a29AcoK0+YwnEqzI6oz3vlRf3xw0zbzt15MzXwItOlnr5nIth6zlY2RENLsOPvhyrKAQA==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.64.0.tgz", + "integrity": "sha512-KA0OshtlcCCXmbfqyZkM5pV3/WNraJf7DkJRLpyrmwPtud57H5BDX7C3k0LPSPxpprfRL+cJDGabF10mvNCoCw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@typescript-eslint/scope-manager": "8.34.1", - "@typescript-eslint/types": "8.34.1", - "@typescript-eslint/typescript-estree": "8.34.1", - "@typescript-eslint/visitor-keys": "8.34.1", - "debug": "^4.3.4" + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3591,20 +2309,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/project-service": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.34.1.tgz", - "integrity": "sha512-nuHlOmFZfuRwLJKDGQOVc0xnQrAmuq1Mj/ISou5044y1ajGNp2BNliIqp7F2LPQ5sForz8lempMFCovfeS1XoA==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.64.0.tgz", + "integrity": "sha512-tk4WpOJ6IEbGrVHaNmM0YRrwAD3exZlIK3iadQNAxh4YKk6jvUQ4ecq18n+v7+meh+cJ3j+D8nbk8sRKhlwLQg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/tsconfig-utils": "^8.34.1", - "@typescript-eslint/types": "^8.34.1", - "debug": "^4.3.4" + "@typescript-eslint/tsconfig-utils": "^8.64.0", + "@typescript-eslint/types": "^8.64.0", + "debug": "^4.4.3" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3614,18 +2332,18 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/scope-manager": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.34.1.tgz", - "integrity": "sha512-beu6o6QY4hJAgL1E8RaXNC071G4Kso2MGmJskCFQhRhg8VOH/FDbC8soP8NHN7e/Hdphwp8G8cE6OBzC8o41ZA==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.64.0.tgz", + "integrity": "sha512-CXEaFdYXjSTgKhisNkwCcJwTP8Pl+fmRrEQrri4nm3vU743bALrxzLmq7fHG/7e6a5xO0lDYeURpZmBuhHk54w==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.34.1", - "@typescript-eslint/visitor-keys": "8.34.1" + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3636,9 +2354,9 @@ } }, "node_modules/@typescript-eslint/tsconfig-utils": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.34.1.tgz", - "integrity": "sha512-K4Sjdo4/xF9NEeA2khOb7Y5nY6NSXBnod87uniVYW9kHP+hNlDV8trUSFeynA2uxWam4gIWgWoygPrv9VMWrYg==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.64.0.tgz", + "integrity": "sha512-2yo8rRNKuzbVWQp5kslhANqZ2uDAeROQHBRZNPu8JDsHmeFNj/XJJhX/FhNUWmkHHvoNsKa6+tHJiig87EzsQw==", "dev": true, "license": "MIT", "engines": { @@ -3649,20 +2367,21 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/type-utils": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.34.1.tgz", - "integrity": "sha512-Tv7tCCr6e5m8hP4+xFugcrwTOucB8lshffJ6zf1mF1TbU67R+ntCc6DzLNKM+s/uzDyv8gLq7tufaAhIBYeV8g==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.64.0.tgz", + "integrity": "sha512-XWG4Fmmv/6SvyS9nH8jWrKs6terwJvE8cyRt1CzYYqzp9OrPhCT4cMc/f7C6RZCwG+qMmiffJS1/qJP8G1URtg==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/typescript-estree": "8.34.1", - "@typescript-eslint/utils": "8.34.1", - "debug": "^4.3.4", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0", + "@typescript-eslint/utils": "8.64.0", + "debug": "^4.4.3", + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3672,14 +2391,14 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/types": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.34.1.tgz", - "integrity": "sha512-rjLVbmE7HR18kDsjNIZQHxmv9RZwlgzavryL5Lnj2ujIRTeXlKtILHgRNmQ3j4daw7zd+mQgy+uyt6Zo6I0IGA==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.64.0.tgz", + "integrity": "sha512-qjhfuTfLXjA4IOzXvz0rTjT01BqEiIgPoUeMwiEjnaHKJMTNo8rH5pYW1a2L/0Dnux2fPC85AeyJoWaGa8WxTA==", "dev": true, "license": "MIT", "engines": { @@ -3691,22 +2410,21 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.34.1.tgz", - "integrity": "sha512-rjCNqqYPuMUF5ODD+hWBNmOitjBWghkGKJg6hiCHzUvXRy6rK22Jd3rwbP2Xi+R7oYVvIKhokHVhH41BxPV5mA==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.64.0.tgz", + "integrity": "sha512-Pztpsn1aCE1oWDvDEfUk31nngvvF7vUB5SwHFEaZIFpvw7WJtqUHHL4plBZDA9HfWJJjL13BdG0YrJInTUvoVA==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/project-service": "8.34.1", - "@typescript-eslint/tsconfig-utils": "8.34.1", - "@typescript-eslint/types": "8.34.1", - "@typescript-eslint/visitor-keys": "8.34.1", - "debug": "^4.3.4", - "fast-glob": "^3.3.2", - "is-glob": "^4.0.3", - "minimatch": "^9.0.4", - "semver": "^7.6.0", - "ts-api-utils": "^2.1.0" + "@typescript-eslint/project-service": "8.64.0", + "@typescript-eslint/tsconfig-utils": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/visitor-keys": "8.64.0", + "debug": "^4.4.3", + "minimatch": "^10.2.2", + "semver": "^7.7.3", + "tinyglobby": "^0.2.15", + "ts-api-utils": "^2.5.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3716,20 +2434,20 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "typescript": ">=4.8.4 <5.9.0" + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/utils": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.34.1.tgz", - "integrity": "sha512-mqOwUdZ3KjtGk7xJJnLbHxTuWVn3GO2WZZuM+Slhkun4+qthLdXx32C8xIXbO1kfCECb3jIs3eoxK3eryk7aoQ==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.64.0.tgz", + "integrity": "sha512-aJUGVB3+U0htrrCjoA8qukw8cm8fNCGAxK/tVoS70k8aeb7DETKeFozRiVFIwEeN9WJLsjaP3ph8I60tY2XZoQ==", "dev": true, "license": "MIT", "dependencies": { - "@eslint-community/eslint-utils": "^4.7.0", - "@typescript-eslint/scope-manager": "8.34.1", - "@typescript-eslint/types": "8.34.1", - "@typescript-eslint/typescript-estree": "8.34.1" + "@eslint-community/eslint-utils": "^4.9.1", + "@typescript-eslint/scope-manager": "8.64.0", + "@typescript-eslint/types": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3739,19 +2457,19 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.34.1.tgz", - "integrity": "sha512-xoh5rJ+tgsRKoXnkBPFRLZ7rjKM0AfVbC68UZ/ECXoDbfggb9RbEySN359acY1vS3qZ0jVTVWzbtfapwm5ztxw==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.64.0.tgz", + "integrity": "sha512-mrtuL8Nsn6gi2H4mo5KMTp823M+3Q19Ew/i+Zlikq20tIMm99C3Ez0dCmkWWnxut20esQvTg8aUSEhMcAOXhEw==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/types": "8.34.1", - "eslint-visitor-keys": "^4.2.1" + "@typescript-eslint/types": "8.64.0", + "eslint-visitor-keys": "^5.0.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -3761,10 +2479,23 @@ "url": "https://opencollective.com/typescript-eslint" } }, + "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz", + "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": "^20.19.0 || ^22.13.0 || >=24" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, "node_modules/@unrs/resolver-binding-android-arm-eabi": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.9.0.tgz", - "integrity": "sha512-h1T2c2Di49ekF2TE8ZCoJkb+jwETKUIPDJ/nO3tJBKlLFPu+fyd93f0rGP/BvArKx2k2HlRM4kqkNarj3dvZlg==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm-eabi/-/resolver-binding-android-arm-eabi-1.12.2.tgz", + "integrity": "sha512-g5T90pqg1bo/7mytQx6F4iBNC0Wsh9cu+z9veDbFjc7HjpesJFWD7QMS0NGStXM075+7dJPPVvBbpZlnrdpi/w==", "cpu": [ "arm" ], @@ -3776,9 +2507,9 @@ ] }, "node_modules/@unrs/resolver-binding-android-arm64": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.9.0.tgz", - "integrity": "sha512-sG1NHtgXtX8owEkJ11yn34vt0Xqzi3k9TJ8zppDmyG8GZV4kVWw44FHwKwHeEFl07uKPeC4ZoyuQaGh5ruJYPA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-android-arm64/-/resolver-binding-android-arm64-1.12.2.tgz", + "integrity": "sha512-YGCRZv/9GLhwmz6mYDeTsm/92BAyR28l6c2ReweVW5pWgfsitWLY8upvfRlGdoyD8HjeTHSYJWyZGD4KJA/nFQ==", "cpu": [ "arm64" ], @@ -3790,9 +2521,9 @@ ] }, "node_modules/@unrs/resolver-binding-darwin-arm64": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.9.0.tgz", - "integrity": "sha512-nJ9z47kfFnCxN1z/oYZS7HSNsFh43y2asePzTEZpEvK7kGyuShSl3RRXnm/1QaqFL+iP+BjMwuB+DYUymOkA5A==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-arm64/-/resolver-binding-darwin-arm64-1.12.2.tgz", + "integrity": "sha512-u9DiNT1auQMO20A9SyTuG3wUgQWB9Z7KjAg0uFuCDR1FsAY8A0CG2S6JpHS1xwm/w1G08bjXZDcyOCjv1WAm2w==", "cpu": [ "arm64" ], @@ -3804,9 +2535,9 @@ ] }, "node_modules/@unrs/resolver-binding-darwin-x64": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.9.0.tgz", - "integrity": "sha512-TK+UA1TTa0qS53rjWn7cVlEKVGz2B6JYe0C++TdQjvWYIyx83ruwh0wd4LRxYBM5HeuAzXcylA9BH2trARXJTw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-darwin-x64/-/resolver-binding-darwin-x64-1.12.2.tgz", + "integrity": "sha512-f7rPLi/T1HVKZu/u6t87lroib16n8vrSzcyxI7lg4BGO9UF26KhQL44sd9eOUgrTYhvRXtWOIZT5PejdPyJfUA==", "cpu": [ "x64" ], @@ -3818,9 +2549,9 @@ ] }, "node_modules/@unrs/resolver-binding-freebsd-x64": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.9.0.tgz", - "integrity": "sha512-6uZwzMRFcD7CcCd0vz3Hp+9qIL2jseE/bx3ZjaLwn8t714nYGwiE84WpaMCYjU+IQET8Vu/+BNAGtYD7BG/0yA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-freebsd-x64/-/resolver-binding-freebsd-x64-1.12.2.tgz", + "integrity": "sha512-BpcOjWCJub6nRZUS2zA20pmLvjtqAtGejETaIyRLiZiQf++cbrjltLA5NN/xaXfqeOBOSlMFbemIl5/S5tljmg==", "cpu": [ "x64" ], @@ -3832,9 +2563,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm-gnueabihf": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.9.0.tgz", - "integrity": "sha512-bPUBksQfrgcfv2+mm+AZinaKq8LCFvt5PThYqRotqSuuZK1TVKkhbVMS/jvSRfYl7jr3AoZLYbDkItxgqMKRkg==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-gnueabihf/-/resolver-binding-linux-arm-gnueabihf-1.12.2.tgz", + "integrity": "sha512-vZTDvdSISZjJx66OzJqtsOhzifbqRjbmI1Mnu49fQDwog5GtDI4QidRiEAYbZCRj9C8YZEW+3ZjqsyS9GR4k2A==", "cpu": [ "arm" ], @@ -3846,9 +2577,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm-musleabihf": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.9.0.tgz", - "integrity": "sha512-uT6E7UBIrTdCsFQ+y0tQd3g5oudmrS/hds5pbU3h4s2t/1vsGWbbSKhBSCD9mcqaqkBwoqlECpUrRJCmldl8PA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm-musleabihf/-/resolver-binding-linux-arm-musleabihf-1.12.2.tgz", + "integrity": "sha512-BiPI+IrIlwcW4nLLMM21+B1dFPzd55yAVgVGrdgDjNef+ch03GdxrcyaIz8X9SsQirh/kCQ7mviyWlMxdh2D7g==", "cpu": [ "arm" ], @@ -3860,9 +2591,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm64-gnu": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.9.0.tgz", - "integrity": "sha512-vdqBh911wc5awE2bX2zx3eflbyv8U9xbE/jVKAm425eRoOVv/VseGZsqi3A3SykckSpF4wSROkbQPvbQFn8EsA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-gnu/-/resolver-binding-linux-arm64-gnu-1.12.2.tgz", + "integrity": "sha512-zJc0H99FEPoFfSrNpa91HYfxzfAJCr502oxNK1cfdC9hlaFI43RT+JFCann9JUgZmLzzntChHyn13Sgn9ljHNg==", "cpu": [ "arm64" ], @@ -3874,9 +2605,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-arm64-musl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.9.0.tgz", - "integrity": "sha512-/8JFZ/SnuDr1lLEVsxsuVwrsGquTvT51RZGvyDB/dOK3oYK2UqeXzgeyq6Otp8FZXQcEYqJwxb9v+gtdXn03eQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-arm64-musl/-/resolver-binding-linux-arm64-musl-1.12.2.tgz", + "integrity": "sha512-KQ3Lki6l+Pz1k/eBipN41ES+YUK30beLGb9YqcB1O542cyLCNE6GaxrfcY3T6EezmGGk84wb5XyO9loTM9tkcA==", "cpu": [ "arm64" ], @@ -3887,10 +2618,38 @@ "linux" ] }, + "node_modules/@unrs/resolver-binding-linux-loong64-gnu": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-gnu/-/resolver-binding-linux-loong64-gnu-1.12.2.tgz", + "integrity": "sha512-3SJGEh1DborhG6pyxvhPzCT4bbSIVihsvgJc13P1bHG7KLdNDaF9T3gsTwFc7Jw/5Y5/iWOjkEx7Zy0NvCGX3Q==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@unrs/resolver-binding-linux-loong64-musl": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-loong64-musl/-/resolver-binding-linux-loong64-musl-1.12.2.tgz", + "integrity": "sha512-jiuG/Obbel7uw1PwHNFfrkiKhLAF6mnyZ6aWlOAVN9WqKm8v0OFGnciJIHu8+CMvXLQ8AD51LPzAoUfT21D5Ew==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, "node_modules/@unrs/resolver-binding-linux-ppc64-gnu": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.9.0.tgz", - "integrity": "sha512-FkJjybtrl+rajTw4loI3L6YqSOpeZfDls4SstL/5lsP2bka9TiHUjgMBjygeZEis1oC8LfJTS8FSgpKPaQx2tQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-ppc64-gnu/-/resolver-binding-linux-ppc64-gnu-1.12.2.tgz", + "integrity": "sha512-q7xRvVpmcfeL+LlZg8Pbbo6QaTZwDU5BaGZbwfhkEsXJn3Was8xYfE0RBH266xZt0rM6B7i8xAYIvjthuUIWHg==", "cpu": [ "ppc64" ], @@ -3902,9 +2661,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-riscv64-gnu": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.9.0.tgz", - "integrity": "sha512-w/NZfHNeDusbqSZ8r/hp8iL4S39h4+vQMc9/vvzuIKMWKppyUGKm3IST0Qv0aOZ1rzIbl9SrDeIqK86ZpUK37w==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-gnu/-/resolver-binding-linux-riscv64-gnu-1.12.2.tgz", + "integrity": "sha512-0CVdx6lcnT3Q9inOH8tsMIOJ6ImndllMjqJHg8RLVdB7Vq4SfkEXl9mCSsVNuNA4MCYycRicCUxPCabVHJRr6A==", "cpu": [ "riscv64" ], @@ -3916,9 +2675,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-riscv64-musl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.9.0.tgz", - "integrity": "sha512-bEPBosut8/8KQbUixPry8zg/fOzVOWyvwzOfz0C0Rw6dp+wIBseyiHKjkcSyZKv/98edrbMknBaMNJfA/UEdqw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-riscv64-musl/-/resolver-binding-linux-riscv64-musl-1.12.2.tgz", + "integrity": "sha512-iOwlRo9vnp6R6ohHQS11n0NnfdXx/omhkocmIfaPRpQhKZ+3BDMkkdRVh53qjkFkpPddf+FETA28NwGN7l5l+w==", "cpu": [ "riscv64" ], @@ -3930,9 +2689,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-s390x-gnu": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.9.0.tgz", - "integrity": "sha512-LDtMT7moE3gK753gG4pc31AAqGUC86j3AplaFusc717EUGF9ZFJ356sdQzzZzkBk1XzMdxFyZ4f/i35NKM/lFA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-s390x-gnu/-/resolver-binding-linux-s390x-gnu-1.12.2.tgz", + "integrity": "sha512-HYJtLfXq94q8iZNFT1lknx258wlkkWhZeUXJRqzKBBUJ00CvZ+N33zgbCqimLjsyw5Va6uUxhVa12mI+kaveEw==", "cpu": [ "s390x" ], @@ -3944,9 +2703,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-x64-gnu": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.9.0.tgz", - "integrity": "sha512-WmFd5KINHIXj8o1mPaT8QRjA9HgSXhN1gl9Da4IZihARihEnOylu4co7i/yeaIpcfsI6sYs33cNZKyHYDh0lrA==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-gnu/-/resolver-binding-linux-x64-gnu-1.12.2.tgz", + "integrity": "sha512-mPsUhunKKDih5O96Y6enDQyHc1SqBPlY1E/SfMWDM3EdJ95Z9CArPeCVwCCqbP45ljvivdEk8Fxn+SIb1rDAJQ==", "cpu": [ "x64" ], @@ -3958,9 +2717,9 @@ ] }, "node_modules/@unrs/resolver-binding-linux-x64-musl": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.9.0.tgz", - "integrity": "sha512-CYuXbANW+WgzVRIl8/QvZmDaZxrqvOldOwlbUjIM4pQ46FJ0W5cinJ/Ghwa/Ng1ZPMJMk1VFdsD/XwmCGIXBWg==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-linux-x64-musl/-/resolver-binding-linux-x64-musl-1.12.2.tgz", + "integrity": "sha512-azrt6+5ydLd8Vt210AAFis/lZevSfPw93EJRIJG+xPu4WCJ8K0kppCTpMyLPcKT7H15M4Jnt2tMp5bOvCkRC6A==", "cpu": [ "x64" ], @@ -3971,10 +2730,24 @@ "linux" ] }, + "node_modules/@unrs/resolver-binding-openharmony-arm64": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-openharmony-arm64/-/resolver-binding-openharmony-arm64-1.12.2.tgz", + "integrity": "sha512-YZ9hP4O0X9PQb8eO980qmLNGH4zT3I9+SZTdt0Pr0YyuGQhYKoOZkV02VzrzyOZJ5xIJ3UFIenKkUkGg8GjgWQ==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, "node_modules/@unrs/resolver-binding-wasm32-wasi": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.9.0.tgz", - "integrity": "sha512-6Rp2WH0OoitMYR57Z6VE8Y6corX8C6QEMWLgOV6qXiJIeZ1F9WGXY/yQ8yDC4iTraotyLOeJ2Asea0urWj2fKQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-wasm32-wasi/-/resolver-binding-wasm32-wasi-1.12.2.tgz", + "integrity": "sha512-tYFDIkMxSflfEc/h92ZWNsZlHSwgimbNHSO3PL2JWQHfCuC2q316jMyYU9TIWZsFK2bQwyK5VAdYgn8ygPj69A==", "cpu": [ "wasm32" ], @@ -3982,16 +2755,18 @@ "license": "MIT", "optional": true, "dependencies": { - "@napi-rs/wasm-runtime": "^0.2.11" + "@emnapi/core": "1.10.0", + "@emnapi/runtime": "1.10.0", + "@napi-rs/wasm-runtime": "^1.1.4" }, "engines": { "node": ">=14.0.0" } }, "node_modules/@unrs/resolver-binding-win32-arm64-msvc": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.9.0.tgz", - "integrity": "sha512-rknkrTRuvujprrbPmGeHi8wYWxmNVlBoNW8+4XF2hXUnASOjmuC9FNF1tGbDiRQWn264q9U/oGtixyO3BT8adQ==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-arm64-msvc/-/resolver-binding-win32-arm64-msvc-1.12.2.tgz", + "integrity": "sha512-qzNyg3xL0VPQmCaUh+N5jSitce6k+uCBfMDesWRnlULOZaqUkaJ0ybdT+UqlAWJoQjuqfIU/0Ptx9bteN4D82g==", "cpu": [ "arm64" ], @@ -4003,9 +2778,9 @@ ] }, "node_modules/@unrs/resolver-binding-win32-ia32-msvc": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.9.0.tgz", - "integrity": "sha512-Ceymm+iBl+bgAICtgiHyMLz6hjxmLJKqBim8tDzpX61wpZOx2bPK6Gjuor7I2RiUynVjvvkoRIkrPyMwzBzF3A==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-ia32-msvc/-/resolver-binding-win32-ia32-msvc-1.12.2.tgz", + "integrity": "sha512-WD9sY00OfpHVGfsnHZoA8jVT+esS/Bg8z8jzxp5BnDCjjwsuKsPQrzswwpFy4J1AUJbXPRfkpcX0mXrzeXW79g==", "cpu": [ "ia32" ], @@ -4017,9 +2792,9 @@ ] }, "node_modules/@unrs/resolver-binding-win32-x64-msvc": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.9.0.tgz", - "integrity": "sha512-k59o9ZyeyS0hAlcaKFezYSH2agQeRFEB7KoQLXl3Nb3rgkqT1NY9Vwy+SqODiLmYnEjxWJVRE/yq2jFVqdIxZw==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/@unrs/resolver-binding-win32-x64-msvc/-/resolver-binding-win32-x64-msvc-1.12.2.tgz", + "integrity": "sha512-nAB74NfSNKknqQ1RrYj6uz8FcXEomu/MATJZxh/x+BArzN2U3JbOYC0APYzUIGhVY3m5hRxA8VPNdPBoG8txlA==", "cpu": [ "x64" ], @@ -4037,9 +2812,9 @@ "license": "ISC" }, "node_modules/abort-controller-x": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/abort-controller-x/-/abort-controller-x-0.4.3.tgz", - "integrity": "sha512-VtUwTNU8fpMwvWGn4xE93ywbogTYsuT+AUxAXOeelbXuQVIwNmC5YLeho9sH4vZ4ITW8414TTAOG1nW6uIVHCA==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/abort-controller-x/-/abort-controller-x-0.5.0.tgz", + "integrity": "sha512-yTt9CI0x+nRfX6BFMenEGP8ooPvErGH6AbFz20C2IeOLIlDsrw/VHpgne3GsCEuTA410IiFiaLVFKmgM4bKEPQ==", "license": "MIT" }, "node_modules/accepts": { @@ -4056,12 +2831,11 @@ } }, "node_modules/acorn": { - "version": "8.15.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.15.0.tgz", - "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", + "version": "8.17.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.17.0.tgz", + "integrity": "sha512-xRQbDb9BnwDafYNn6Vwl839DYVjqXYb1XVGtWAZ1kcDc6iwAL4hg3B1dZlRiuENFeO2H53gFG3in621AdERVAg==", "dev": true, "license": "MIT", - "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -4124,9 +2898,9 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.15.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.15.0.tgz", + "integrity": "sha512-fgFx7Hfoq60ytK2c7DhnF8jIvzYgOMxfugjLOSMHjLIPgenqa7S7oaagATUq99mV6IYvN2tRmC0wnTYX6iPbMw==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", @@ -4139,21 +2913,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "license": "MIT", - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/ansi-regex": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", @@ -4179,9 +2938,9 @@ } }, "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.1.0.tgz", + "integrity": "sha512-tLIEcj5GuR2RSTnxNKdkK0dJ/GrC7P38sUkiDmDuHfsHmbagTFAxDVIBltoklXEVIQ/f14IL8IMJ5pn9Hez1Ew==", "license": "ISC" }, "node_modules/are-we-there-yet": { @@ -4289,6 +3048,27 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array.prototype.findlast": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlast/-/array.prototype.findlast-1.2.5.tgz", + "integrity": "sha512-CVvd6FHg1Z3POpBLxO6E6zr+rSKEQ9L6rZHAaY7lLfhKsWYUBBOuMs0e9o24oopj6H+geRCX0YJ+TJLBK2eHyQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array.prototype.findlastindex": { "version": "1.2.6", "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.6.tgz", @@ -4349,6 +3129,23 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.4.tgz", + "integrity": "sha512-p6Fx8B7b7ZhL/gmUsAy0D15WhvDccw3mnGNbZpi3pmeJdxtWsj2jEaI4Y6oo3XiHfzuSgPwKc04MYt6KgvC/wA==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.3", + "es-errors": "^1.3.0", + "es-shim-unscopables": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/arraybuffer-to-string": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/arraybuffer-to-string/-/arraybuffer-to-string-1.0.2.tgz", @@ -4455,10 +3252,14 @@ "license": "MIT" }, "node_modules/balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT" + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz", + "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==", + "dev": true, + "license": "MIT", + "engines": { + "node": "18 || 20 || >=22" + } }, "node_modules/basic-auth": { "version": "2.0.1", @@ -4514,23 +3315,23 @@ "license": "MIT" }, "node_modules/body-parser": { - "version": "1.20.3", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.3.tgz", - "integrity": "sha512-7rAxByjUMqQ3/bHJy7D6OGXvx/MMc4IqBn/X0fcM1QUcAItpZrBEYhWGem+tzXH90c+G01ypMcYJBO9Y30203g==", + "version": "1.20.6", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.6.tgz", + "integrity": "sha512-p5tAzS57i5MV9fZFDj9LeIiTZEufbSe2eDozP+ElheSUq1m74CRq1jI4mYNDdVs9vQztXFLuk/Gd6BWTdwRJ5g==", "license": "MIT", "dependencies": { - "bytes": "3.1.2", + "bytes": "~3.1.2", "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.13.0", - "raw-body": "2.5.2", + "destroy": "~1.2.0", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "on-finished": "~2.4.1", + "qs": "~6.15.1", + "raw-body": "~2.5.3", "type-is": "~1.6.18", - "unpipe": "1.0.0" + "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8", @@ -4546,6 +3347,18 @@ "ms": "2.0.0" } }, + "node_modules/body-parser/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -4553,31 +3366,22 @@ "license": "MIT" }, "node_modules/bowser": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz", - "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==", + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.14.1.tgz", + "integrity": "sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==", "license": "MIT" }, "node_modules/brace-expansion": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz", - "integrity": "sha512-Jt0vHyM+jmUBqojB7E1NIYadt0vI0Qxjxd2TErW94wDz+E2LAm5vKMXXwg6ZZBTHPuUlDgQHKXvjGBdfcF1ZDQ==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/braces": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", - "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "version": "5.0.9", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.9.tgz", + "integrity": "sha512-ScQ4IuvIEF1TMlP7Zt+vjJ//9zlPb2SDcxWxM3bk8s6t6GGdJ7KO1dCcTidOPJKePW30LE/2cT7wCyPho9/Wxg==", "dev": true, "license": "MIT", "dependencies": { - "fill-range": "^7.1.1" + "balanced-match": "^4.0.2" }, "engines": { - "node": ">=8" + "node": "20 || >=22" } }, "node_modules/brfs": { @@ -4595,6 +3399,27 @@ "brfs": "bin/cmd.js" } }, + "node_modules/brfs/node_modules/resolve": { + "version": "1.22.12", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.12.tgz", + "integrity": "sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "is-core-module": "^2.16.1", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/bson": { "version": "5.5.1", "resolved": "https://registry.npmjs.org/bson/-/bson-5.5.1.tgz", @@ -4677,15 +3502,15 @@ } }, "node_modules/call-bind": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.8.tgz", - "integrity": "sha512-oKlSFMcMwpUg2ednkhQ454wfWiU/ul3CkJe/PEHcTKuiX6RpbehUiFMXu13HalGZxfUwCQzZG747YXBn1im9ww==", + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.9.tgz", + "integrity": "sha512-a/hy+pNsFUTR+Iz8TCJvXudKVLAnz/DyeSUo10I5yvFDQJBFU2s9uqQpoSrJlroHUKoKqzg+epxyP9lqFdzfBQ==", "dev": true, "license": "MIT", "dependencies": { - "call-bind-apply-helpers": "^1.0.0", - "es-define-property": "^1.0.0", - "get-intrinsic": "^1.2.4", + "call-bind-apply-helpers": "^1.0.2", + "es-define-property": "^1.0.1", + "get-intrinsic": "^1.3.0", "set-function-length": "^1.2.2" }, "engines": { @@ -4744,6 +3569,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", @@ -4757,9 +3583,9 @@ } }, "node_modules/chardet": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.1.0.tgz", - "integrity": "sha512-bNFETTG/pM5ryzQ9Ad0lJOTa6HWD/YsScAR3EnCPZRPlQh77JocYktSHOUHelyhm8IARL+o4c4F1bP5KVOjiRA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-2.2.0.tgz", + "integrity": "sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==", "license": "MIT" }, "node_modules/chownr": { @@ -4976,18 +3802,18 @@ "license": "MIT" }, "node_modules/cookie": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.1.tgz", - "integrity": "sha512-6DnInpx7SJ2AK3+CTUE/ZM0vWTUboZCegxhC2xiIydHR9jNuTAASBrfEpHhiGOZw/nX51bHt6YQl8jsGo4y/0w==", + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", + "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", "license": "MIT", "engines": { "node": ">= 0.6" } }, "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.7.tgz", + "integrity": "sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==", "license": "MIT" }, "node_modules/copyfiles": { @@ -5010,10 +3836,17 @@ "copyup": "copyfiles" } }, + "node_modules/copyfiles/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/copyfiles/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -5022,9 +3855,9 @@ } }, "node_modules/copyfiles/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -5041,9 +3874,9 @@ "license": "MIT" }, "node_modules/cors": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "version": "2.8.6", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", + "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", "license": "MIT", "dependencies": { "object-assign": "^4", @@ -5051,6 +3884,10 @@ }, "engines": { "node": ">= 0.10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/crc": { @@ -5070,6 +3907,23 @@ } } }, + "node_modules/cron": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/cron/-/cron-4.4.0.tgz", + "integrity": "sha512-fkdfq+b+AHI4cKdhZlppHveI/mgz2qpiYxcm+t5E5TsxX7QrLS1VE0+7GENEk9z0EeGPcpSciGv6ez24duWhwQ==", + "license": "MIT", + "dependencies": { + "@types/luxon": "~3.7.0", + "luxon": "~3.7.0" + }, + "engines": { + "node": ">=18.x" + }, + "funding": { + "type": "ko-fi", + "url": "https://ko-fi.com/intcreator" + } + }, "node_modules/cross-env": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", @@ -5105,9 +3959,9 @@ } }, "node_modules/csv-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/csv-parser/-/csv-parser-3.2.0.tgz", - "integrity": "sha512-fgKbp+AJbn1h2dcAHKIdKNSSjfp43BZZykXsCjzALjKy80VXQNHPFJ6T9Afwdzoj24aMkq8GwDS7KGcDPpejrA==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/csv-parser/-/csv-parser-3.2.1.tgz", + "integrity": "sha512-v8RPMSglouR9od735SnwSxLBbCJqEPSbgm1R5qfr8yIiMUCEFjox56kRZid0SvgHJEkxeIEu3+a9QS3YRh7CuA==", "license": "MIT", "bin": { "csv-parser": "bin/csv-parser" @@ -5202,9 +4056,9 @@ } }, "node_modules/debug": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz", - "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -5329,9 +4183,9 @@ } }, "node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", "license": "Apache-2.0", "engines": { "node": ">=8" @@ -5363,9 +4217,9 @@ } }, "node_modules/dotenv": { - "version": "16.5.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.5.0.tgz", - "integrity": "sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg==", + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz", + "integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==", "license": "BSD-2-Clause", "engines": { "node": ">=12" @@ -5452,12 +4306,6 @@ "safer-buffer": "^2.1.0" } }, - "node_modules/ecc-jsbn/node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "license": "MIT" - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -5512,9 +4360,9 @@ } }, "node_modules/es-abstract": { - "version": "1.24.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.0.tgz", - "integrity": "sha512-WSzPgsdLtTcQwm4CROfS5ju2Wa1QQcVeT37jFjYzdFz1r9ahadC8B8/a4qxJxM+09F18iumCdRmlr96ZYkQvEg==", + "version": "1.24.2", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.24.2.tgz", + "integrity": "sha512-2FpH9Q5i2RRwyEP1AylXe6nYLR5OhaJTZwmlcP0dL/+JCbgg7yyEo/sEK6HeGZRf3dFpWwThaRHVApXSkW3xeg==", "dev": true, "license": "MIT", "dependencies": { @@ -5580,6 +4428,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/es-abstract-get": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-abstract-get/-/es-abstract-get-1.0.0.tgz", + "integrity": "sha512-6PMWXpdhshVvFp+FoWYs1EvG1Nj0tvk0dZM+XcK0xMEM1czRVcP6ohqPWHy6qPagSpC8j4+p89WXlT+xXJs/fg==", + "dev": true, + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "es-object-atoms": "^1.1.2", + "is-callable": "^1.2.7", + "object-inspect": "^1.13.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/es-define-property": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", @@ -5598,10 +4465,38 @@ "node": ">= 0.4" } }, + "node_modules/es-iterator-helpers": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/es-iterator-helpers/-/es-iterator-helpers-1.4.0.tgz", + "integrity": "sha512-c/A0P0oxkACDc+cKWw8evLXK83oBKgn0qPOqCYT4x9uolpCIJAcYvJC9QYKNDRPsTeGyCrQ326jrvgZWdCdK5Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-abstract": "^1.24.2", + "es-errors": "^1.3.0", + "es-set-tostringtag": "^2.1.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.3.0", + "globalthis": "^1.0.4", + "gopd": "^1.2.0", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "iterator.prototype": "^1.1.5", + "math-intrinsics": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/es-object-atoms": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz", - "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", + "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0" @@ -5640,15 +4535,18 @@ } }, "node_modules/es-to-primitive": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.0.tgz", - "integrity": "sha512-w+5mJ3GuFL+NjVtJlvydShqE1eN3h3PbI7/5LAsYJP/2qtuMXjfL2LpHSRqo4b4eSF5K/DH1JXKUAHSB2UW50g==", + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.3.4.tgz", + "integrity": "sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==", "dev": true, "license": "MIT", "dependencies": { + "es-abstract-get": "^1.0.0", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", "is-callable": "^1.2.7", - "is-date-object": "^1.0.5", - "is-symbol": "^1.0.4" + "is-date-object": "^1.1.0", + "is-symbol": "^1.1.1" }, "engines": { "node": ">= 0.4" @@ -5850,27 +4748,25 @@ } }, "node_modules/eslint": { - "version": "9.29.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.29.0.tgz", - "integrity": "sha512-GsGizj2Y1rCWDu6XoEekL3RLilp0voSePurjZIkxL3wlm5o5EC9VpgaP7lrCvjnkuLvzFBQWB3vWB3K5KQTveQ==", + "version": "9.39.5", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.5.tgz", + "integrity": "sha512-DgZS62aPLXKlnxILS/AYCoRvHaZeXceIzlXPkkGGzJWSow1aEk0lbTlxUSlyjC8jcaKxAdOnTDz+o1JFSBsyjw==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { - "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", - "@eslint/config-array": "^0.20.1", - "@eslint/config-helpers": "^0.2.1", - "@eslint/core": "^0.14.0", - "@eslint/eslintrc": "^3.3.1", - "@eslint/js": "9.29.0", - "@eslint/plugin-kit": "^0.3.1", + "@eslint/config-array": "^0.21.2", + "@eslint/config-helpers": "^0.4.2", + "@eslint/core": "^0.17.0", + "@eslint/eslintrc": "^3.3.6", + "@eslint/js": "9.39.5", + "@eslint/plugin-kit": "^0.4.1", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", - "@types/json-schema": "^7.0.15", - "ajv": "^6.12.4", + "ajv": "^6.14.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", @@ -5889,7 +4785,7 @@ "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", + "minimatch": "^3.1.5", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, @@ -5911,16 +4807,41 @@ } } }, + "node_modules/eslint-import-context": { + "version": "0.1.9", + "resolved": "https://registry.npmjs.org/eslint-import-context/-/eslint-import-context-0.1.9.tgz", + "integrity": "sha512-K9Hb+yRaGAGUbwjhFNHvSmmkZs9+zbuoe3kFQ4V1wYjrepUFYM2dZAfNtjbbj3qsPfUfsA68Bx/ICWQMi+C8Eg==", + "dev": true, + "license": "MIT", + "dependencies": { + "get-tsconfig": "^4.10.1", + "stable-hash-x": "^0.2.0" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint-import-context" + }, + "peerDependencies": { + "unrs-resolver": "^1.0.0" + }, + "peerDependenciesMeta": { + "unrs-resolver": { + "optional": true + } + } + }, "node_modules/eslint-import-resolver-node": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", - "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.10.tgz", + "integrity": "sha512-tRrKqFyCaKict5hOd244sL6EQFNycnMQnBe+j8uqGNXYzsImGbGUU4ibtoaBmv5FLwJwcFJNeg1GeVjQfbMrDQ==", "dev": true, "license": "MIT", "dependencies": { "debug": "^3.2.7", - "is-core-module": "^2.13.0", - "resolve": "^1.22.4" + "is-core-module": "^2.16.1", + "resolve": "^2.0.0-next.6" } }, "node_modules/eslint-import-resolver-node/node_modules/debug": { @@ -5934,22 +4855,22 @@ } }, "node_modules/eslint-import-resolver-typescript": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.10.1.tgz", - "integrity": "sha512-A1rHYb06zjMGAxdLSkN2fXPBwuSaQ0iO5M/hdyS0Ajj1VBaRp0sPD3dn1FhME3c/JluGFbwSxyCfqdSbtQLAHQ==", + "version": "4.4.5", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-4.4.5.tgz", + "integrity": "sha512-nbE5XLph6TLtGYcu/U6e6ZVXyKBhbDWK5cLGk76eJ7NdZpwf1P9EFkpt1Z01mNZNrrilsAYWKH6zUkL4reoXbw==", "dev": true, "license": "ISC", "dependencies": { - "@nolyfill/is-core-module": "1.0.39", - "debug": "^4.4.0", - "get-tsconfig": "^4.10.0", + "debug": "^4.4.1", + "eslint-import-context": "^0.1.8", + "get-tsconfig": "^4.10.1", "is-bun-module": "^2.0.0", - "stable-hash": "^0.0.5", - "tinyglobby": "^0.2.13", - "unrs-resolver": "^1.6.2" + "stable-hash-x": "^0.2.0", + "tinyglobby": "^0.2.14", + "unrs-resolver": "^1.7.11" }, "engines": { - "node": "^14.18.0 || >=16.0.0" + "node": "^16.17.0 || >=18.6.0" }, "funding": { "url": "https://opencollective.com/eslint-import-resolver-typescript" @@ -5969,9 +4890,9 @@ } }, "node_modules/eslint-module-utils": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz", - "integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.14.0.tgz", + "integrity": "sha512-W2WCRZ9Dqntd+2u8jJcVMV2PKulc6RdLgUUoh/yQr3uB6lo/ZOeGx11sv60/8S4QFFKNslAlWhr9u0Ef7ZW6Ig==", "dev": true, "license": "MIT", "dependencies": { @@ -5997,31 +4918,30 @@ } }, "node_modules/eslint-plugin-import": { - "version": "2.31.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.31.0.tgz", - "integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==", + "version": "2.32.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.32.0.tgz", + "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", - "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", - "array-includes": "^3.1.8", - "array.prototype.findlastindex": "^1.2.5", - "array.prototype.flat": "^1.3.2", - "array.prototype.flatmap": "^1.3.2", + "array-includes": "^3.1.9", + "array.prototype.findlastindex": "^1.2.6", + "array.prototype.flat": "^1.3.3", + "array.prototype.flatmap": "^1.3.3", "debug": "^3.2.7", "doctrine": "^2.1.0", "eslint-import-resolver-node": "^0.3.9", - "eslint-module-utils": "^2.12.0", + "eslint-module-utils": "^2.12.1", "hasown": "^2.0.2", - "is-core-module": "^2.15.1", + "is-core-module": "^2.16.1", "is-glob": "^4.0.3", "minimatch": "^3.1.2", "object.fromentries": "^2.0.8", "object.groupby": "^1.0.3", - "object.values": "^1.2.0", + "object.values": "^1.2.1", "semver": "^6.3.1", - "string.prototype.trimend": "^1.0.8", + "string.prototype.trimend": "^1.0.9", "tsconfig-paths": "^3.15.0" }, "engines": { @@ -6031,10 +4951,17 @@ "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 || ^9" } }, + "node_modules/eslint-plugin-import/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/eslint-plugin-import/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -6053,9 +4980,9 @@ } }, "node_modules/eslint-plugin-import/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -6075,6 +5002,80 @@ "semver": "bin/semver.js" } }, + "node_modules/eslint-plugin-react": { + "version": "7.37.5", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.5.tgz", + "integrity": "sha512-Qteup0SqU15kdocexFNAJMvCJEfa2xUKNV4CC1xsVMrIIqEy3SQ/rqyxCWNzfrd3/ldy6HMlD2e0JDVpDg2qIA==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.8", + "array.prototype.findlast": "^1.2.5", + "array.prototype.flatmap": "^1.3.3", + "array.prototype.tosorted": "^1.1.4", + "doctrine": "^2.1.0", + "es-iterator-helpers": "^1.2.1", + "estraverse": "^5.3.0", + "hasown": "^2.0.2", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.9", + "object.fromentries": "^2.0.8", + "object.values": "^1.2.1", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.5", + "semver": "^6.3.1", + "string.prototype.matchall": "^4.0.12", + "string.prototype.repeat": "^1.0.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7" + } + }, + "node_modules/eslint-plugin-react/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, + "node_modules/eslint-plugin-react/node_modules/brace-expansion": { + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-react/node_modules/minimatch": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-scope": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz", @@ -6105,10 +5106,17 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true, + "license": "MIT" + }, "node_modules/eslint/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "dev": true, "license": "MIT", "dependencies": { @@ -6116,10 +5124,20 @@ "concat-map": "0.0.1" } }, + "node_modules/eslint/node_modules/ignore": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", + "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4" + } + }, "node_modules/eslint/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "dev": true, "license": "ISC", "dependencies": { @@ -6176,9 +5194,9 @@ } }, "node_modules/esquery": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz", - "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz", + "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -6245,39 +5263,39 @@ } }, "node_modules/express": { - "version": "4.21.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz", - "integrity": "sha512-28HqgMZAmih1Czt9ny7qr6ek2qddF4FclbMzwhCREB6OFfH+rXAnuNCwo1/wFvrtbgsQDb4kSbX9de9lFbrXnA==", + "version": "4.22.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.22.2.tgz", + "integrity": "sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==", "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.3", - "content-disposition": "0.5.4", + "body-parser": "~1.20.5", + "content-disposition": "~0.5.4", "content-type": "~1.0.4", - "cookie": "0.7.1", - "cookie-signature": "1.0.6", + "cookie": "~0.7.1", + "cookie-signature": "~1.0.6", "debug": "2.6.9", "depd": "2.0.0", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "finalhandler": "1.3.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", + "finalhandler": "~1.3.1", + "fresh": "~0.5.2", + "http-errors": "~2.0.0", "merge-descriptors": "1.0.3", "methods": "~1.1.2", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "parseurl": "~1.3.3", - "path-to-regexp": "0.1.12", + "path-to-regexp": "~0.1.12", "proxy-addr": "~2.0.7", - "qs": "6.13.0", + "qs": "~6.15.1", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", - "send": "0.19.0", - "serve-static": "1.16.2", + "send": "~0.19.0", + "serve-static": "~1.16.2", "setprototypeof": "1.2.0", - "statuses": "2.0.1", + "statuses": "~2.0.1", "type-is": "~1.6.18", "utils-merge": "1.0.1", "vary": "~1.1.2" @@ -6347,36 +5365,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, - "node_modules/fast-glob": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", - "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==", - "dev": true, - "license": "MIT", - "dependencies": { - "@nodelib/fs.stat": "^2.0.2", - "@nodelib/fs.walk": "^1.2.3", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.8" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/node_modules/glob-parent": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", - "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", - "dev": true, - "license": "ISC", - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", @@ -6389,44 +5377,15 @@ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", "license": "MIT" }, - "node_modules/fast-xml-parser": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz", - "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - }, - { - "type": "paypal", - "url": "https://paypal.me/naturalintelligence" - } - ], - "license": "MIT", - "dependencies": { - "strnum": "^1.0.5" - }, - "bin": { - "fxparser": "src/cli/cli.js" - } - }, - "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", - "dev": true, - "license": "ISC", - "dependencies": { - "reusify": "^1.0.4" - } - }, "node_modules/fdir": { - "version": "6.4.6", - "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", - "integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", + "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==", "dev": true, "license": "MIT", + "engines": { + "node": ">=12.0.0" + }, "peerDependencies": { "picomatch": "^3 || ^4" }, @@ -6459,18 +5418,33 @@ } }, "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.6.tgz", + "integrity": "sha512-5giy2PkLYY1cP39p17Ech+2xlpTRL9HLspOfEgm0L6CwBXBTgsK5ou0JtzYuepxkaQ/tvhCFIJ5uXo0OrM2DxA==", "license": "Apache-2.0", "dependencies": { "minimatch": "^5.0.1" } }, + "node_modules/filelist/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.4.tgz", + "integrity": "sha512-hGfVzPxthbf3+2yjg/RBs60cB0FhqBS/zvdV/4wn4/BmN0bNMMHPc4V/BbFieqf1TKAGGAHnY4eSjajCl0f2Xg==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0" + } + }, "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "version": "5.1.9", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.9.tgz", + "integrity": "sha512-7o1wEA2RyMP7Iu7GNba9vc0RWWGACJOCZBJX2GJWip0ikV+wcOsgVuY9uE8CPiyQhkGFSlhuSkZPavN7u1c2Fw==", "license": "ISC", "dependencies": { "brace-expansion": "^2.0.1" @@ -6479,31 +5453,18 @@ "node": ">=10" } }, - "node_modules/fill-range": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", - "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", - "dev": true, - "license": "MIT", - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/finalhandler": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz", - "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.2.tgz", + "integrity": "sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==", "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~2.0.0", "escape-html": "~1.0.3", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "parseurl": "~1.3.3", - "statuses": "2.0.1", + "statuses": "~2.0.2", "unpipe": "~1.0.0" }, "engines": { @@ -6557,9 +5518,9 @@ } }, "node_modules/flatted": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz", - "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==", + "version": "3.4.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz", + "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==", "dev": true, "license": "ISC" }, @@ -6689,18 +5650,21 @@ } }, "node_modules/function.prototype.name": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.8.tgz", - "integrity": "sha512-e5iwyodOHhbMr/yNrc7fDYG4qlbIvI5gajyzPnb5TCwyhjApznQh1BMFou9b30SevY43gCJKXycoCBjMbsuW0Q==", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.2.0.tgz", + "integrity": "sha512-jObKIik1P2QjPHP5nz5BaOtUlfgS0fWo8IUByNXkM+o+02sJOi94em77GwJKQSJ3gfPHdgzLNrHc1uokV4P/ew==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.3", - "define-properties": "^1.2.1", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "es-define-property": "^1.0.1", + "es-errors": "^1.3.0", "functions-have-names": "^1.2.3", - "hasown": "^2.0.2", - "is-callable": "^1.2.7" + "has-property-descriptors": "^1.0.2", + "hasown": "^2.0.4", + "is-callable": "^1.2.7", + "is-document.all": "^1.0.0" }, "engines": { "node": ">= 0.4" @@ -6746,6 +5710,16 @@ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", "license": "ISC" }, + "node_modules/generator-function": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/generator-function/-/generator-function-2.0.1.tgz", + "integrity": "sha512-SFdFmIJi+ybC0vjlHN0ZGVGHc3lgE0DxPAT0djjVg+kjOnSqclqmj0KQ7ykTOLP6YxoqOvuAODGdcHJn+43q3g==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, "node_modules/generic-pool": { "version": "3.9.0", "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz", @@ -6841,9 +5815,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", - "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "version": "4.14.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.14.0.tgz", + "integrity": "sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==", "dev": true, "license": "MIT", "dependencies": { @@ -6866,7 +5840,7 @@ "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "deprecated": "Glob versions prior to v9 are no longer supported", + "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", @@ -6896,10 +5870,16 @@ "node": ">=10.13.0" } }, + "node_modules/glob/node_modules/balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" + }, "node_modules/glob/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", + "version": "1.1.18", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.18.tgz", + "integrity": "sha512-Edep/X9fGqVNmzKBVsDYIOtD+z1tuezV70LBjdCst9Tqu76lsnvRiZ6oTic1n+/BIwX6QDGAO94PN4N2SADvtw==", "license": "MIT", "dependencies": { "balanced-match": "^1.0.0", @@ -6907,9 +5887,9 @@ } }, "node_modules/glob/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz", + "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==", "license": "ISC", "dependencies": { "brace-expansion": "^1.1.7" @@ -6990,13 +5970,6 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, - "node_modules/graphemer": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", - "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", - "dev": true, - "license": "MIT" - }, "node_modules/har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -7046,6 +6019,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "license": "MIT", "engines": { "node": ">=8" @@ -7114,9 +6088,9 @@ "license": "ISC" }, "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", + "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", "license": "MIT", "dependencies": { "function-bind": "^1.1.2" @@ -7147,19 +6121,23 @@ "license": "BSD-2-Clause" }, "node_modules/http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", + "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", "license": "MIT", "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" + "depd": "~2.0.0", + "inherits": "~2.0.4", + "setprototypeof": "~1.2.0", + "statuses": "~2.0.2", + "toidentifier": "~1.0.1" }, "engines": { "node": ">= 0.8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/http-signature": { @@ -7204,21 +6182,25 @@ } }, "node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", + "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "safer-buffer": ">= 2.1.2 < 3.0.0" }, "engines": { "node": ">=0.10.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/ignore": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz", - "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==", + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.6.tgz", + "integrity": "sha512-BAg6QkE8W+TuQLrrw0Ugr7HegXduRuuj8/ti2kSOc+jz1dmx8/WNcjr6XGnq5YpDWxFwwaavqD0+jIUOKelTsw==", "dev": true, "license": "MIT", "engines": { @@ -7338,22 +6320,18 @@ "license": "MIT" }, "node_modules/ip-address": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", - "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.2.0.tgz", + "integrity": "sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==", "license": "MIT", - "dependencies": { - "jsbn": "1.1.0", - "sprintf-js": "^1.1.3" - }, "engines": { "node": ">= 12" } }, "node_modules/ip2location-nodejs": { - "version": "9.6.3", - "resolved": "https://registry.npmjs.org/ip2location-nodejs/-/ip2location-nodejs-9.6.3.tgz", - "integrity": "sha512-npgq6Dwk0G53GKbxUCzZvosr0KPfreufohFKSzM7vAGtbmpuO2KwULQb5AxkCtlBIZ7xFShri7R1iVUbe7BKTw==", + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/ip2location-nodejs/-/ip2location-nodejs-9.8.0.tgz", + "integrity": "sha512-3O7S1A+eevRkwQwHYdK7ex2PuXAc3EMNJDHT4dkBIUlqE3hB/i5BNbmQImJw4kAj/rslPQHa5In4oTV/N04vRw==", "license": "MIT", "dependencies": { "csv-parser": "^3.0.0" @@ -7510,12 +6488,12 @@ } }, "node_modules/is-core-module": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.1.tgz", - "integrity": "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w==", + "version": "2.16.2", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.16.2.tgz", + "integrity": "sha512-evOr8xfXKxE6qSR0hSXL2r3sd7ALj8+7jQEUvPYcm5sgZFdJ+AYzT6yNmJenvIYQBgIGwfwz08sL8zoL7yq2BA==", "license": "MIT", "dependencies": { - "hasown": "^2.0.2" + "hasown": "^2.0.3" }, "engines": { "node": ">= 0.4" @@ -7559,6 +6537,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/is-document.all": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-document.all/-/is-document.all-1.0.0.tgz", + "integrity": "sha512-+XSoyS05OdBbhFuELhgTCpFNHkpBOJqtsZfUFFpe5QTw+9Sjbh8zitxhQkYAo6wV7e1Vb8cAPvpCk9jGam/82g==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bound": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -7595,14 +6589,15 @@ } }, "node_modules/is-generator-function": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.0.tgz", - "integrity": "sha512-nPUB5km40q9e8UfN/Zc24eLlzdSf9OfKByBw9CIdw4H1giPMeA0OIJvbchsCu4npfI2QcMVBsGEBHKZ7wLTWmQ==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-generator-function/-/is-generator-function-1.1.2.tgz", + "integrity": "sha512-upqt1SkGkODW9tsGNG5mtXTXtECizwtS2kA161M+gJPc1xdb/Ax629af6YrTwcOeQHbewrPNlE5Dx7kzvXTizA==", "dev": true, "license": "MIT", "dependencies": { - "call-bound": "^1.0.3", - "get-proto": "^1.0.0", + "call-bound": "^1.0.4", + "generator-function": "^2.0.0", + "get-proto": "^1.0.1", "has-tostringtag": "^1.0.2", "safe-regex-test": "^1.1.0" }, @@ -7664,16 +6659,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/is-number-object": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.1.1.tgz", @@ -7888,16 +6873,33 @@ "integrity": "sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==", "license": "MIT" }, + "node_modules/iterator.prototype": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/iterator.prototype/-/iterator.prototype-1.1.5.tgz", + "integrity": "sha512-H0dkQoCa3b2VEeKQBOxFph+JAbcrQdE7KC0UkqwpLmv2EC4P41QXP+rqo9wYodACiG5/WM5s9oDApTU8utwj9g==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "get-proto": "^1.0.0", + "has-symbols": "^1.1.0", + "set-function-name": "^2.0.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/jake": { - "version": "10.9.2", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.2.tgz", - "integrity": "sha512-2P4SQ0HrLQ+fw6llpLnOaGAvN2Zu6778SJMrCUwns4fOoG9ayrTiZk3VV8sCPkVZF8ab0zksVpS8FDY5pRCNBA==", + "version": "10.9.4", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz", + "integrity": "sha512-wpHYzhxiVQL+IV05BLE2Xn34zW1S223hvjtqk0+gsPrwd/8JNLXJgZZM/iPFsYc1xyphF+6M6EvdE5E9MBGkDA==", "license": "Apache-2.0", "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", + "async": "^3.2.6", "filelist": "^1.0.4", - "minimatch": "^3.1.2" + "picocolors": "^1.1.1" }, "bin": { "jake": "bin/cli.js" @@ -7906,52 +6908,34 @@ "node": ">=10" } }, - "node_modules/jake/node_modules/brace-expansion": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz", - "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==", - "license": "MIT", - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "node_modules/jake/node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "license": "ISC", - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/joi": { - "version": "17.13.3", - "resolved": "https://registry.npmjs.org/joi/-/joi-17.13.3.tgz", - "integrity": "sha512-otDA4ldcIx+ZXsKHWmp0YizCweVRZG96J10b0FevjfuncLO1oX59THoAmHkNubYJ+9gWsYsp5k8v4ib6oDv1fA==", - "license": "BSD-3-Clause", - "dependencies": { - "@hapi/hoek": "^9.3.0", - "@hapi/topo": "^5.1.0", - "@sideway/address": "^4.1.5", - "@sideway/formula": "^3.0.1", - "@sideway/pinpoint": "^2.0.0" - } - }, "node_modules/jpeg-js": { "version": "0.3.7", "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.3.7.tgz", "integrity": "sha512-9IXdWudL61npZjvLuVe/ktHiA41iE8qFyLB+4VDTblEsWBzeg8WQTlktdUK4CdncUqtUgUg0bbOmTE2bKBKaBQ==", "license": "BSD-3-Clause" }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "dev": true, + "license": "MIT" + }, + "node_modules/js-yaml": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.3.0.tgz", + "integrity": "sha512-1td788aAnnZ5qs7V2QIRl1owjtYpbKt749Y3xauqQgwIIGF/xXWz1wMTEBx5O3LK3lXLVuqXPdPxj2BoFHaW9Q==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/puzrin" + }, + { + "type": "github", + "url": "https://github.com/sponsors/nodeca" + } + ], "license": "MIT", "dependencies": { "argparse": "^2.0.1" @@ -7961,9 +6945,9 @@ } }, "node_modules/jsbn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", - "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", "license": "MIT" }, "node_modules/json-buffer": { @@ -8034,6 +7018,22 @@ "node": ">=0.6.0" } }, + "node_modules/jsx-ast-utils": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.5.tgz", + "integrity": "sha512-ZZow9HBI5O6EPgSJLUb8n2NKgmVWTwCvHGwFuJlMjvLFqlGG6pjirPhtdsseaLZjSibD8eegzmYpUZwoIlj2cQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flat": "^1.3.1", + "object.assign": "^4.1.4", + "object.values": "^1.1.6" + }, + "engines": { + "node": ">=4.0" + } + }, "node_modules/kareem": { "version": "2.5.1", "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.5.1.tgz", @@ -8113,6 +7113,19 @@ "integrity": "sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==", "license": "Apache-2.0" }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, "node_modules/lowercase-keys": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", @@ -8122,6 +7135,15 @@ "node": ">=8" } }, + "node_modules/luxon": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-3.7.2.tgz", + "integrity": "sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==", + "license": "MIT", + "engines": { + "node": ">=12" + } + }, "node_modules/magic-string": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.25.1.tgz", @@ -8207,16 +7229,6 @@ "node": ">=0.10.0" } }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 8" - } - }, "node_modules/methods": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", @@ -8226,33 +7238,6 @@ "node": ">= 0.6" } }, - "node_modules/micromatch": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.8.tgz", - "integrity": "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==", - "dev": true, - "license": "MIT", - "dependencies": { - "braces": "^3.0.3", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/micromatch/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, "node_modules/mii-js": { "version": "1.0.4", "resolved": "git+ssh://git@github.com/PretendoNetwork/mii-js.git#f1741e1f82771dd7c753fd408230373d33caa184", @@ -8305,16 +7290,16 @@ } }, "node_modules/minimatch": { - "version": "9.0.5", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", - "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "version": "10.2.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz", + "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==", "dev": true, - "license": "ISC", + "license": "BlueOak-1.0.0", "dependencies": { - "brace-expansion": "^2.0.1" + "brace-expansion": "^5.0.5" }, "engines": { - "node": ">=16 || 14 >=14.17" + "node": "18 || 20 || >=22" }, "funding": { "url": "https://github.com/sponsors/isaacs" @@ -8436,11 +7421,10 @@ } }, "node_modules/mongoose": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.8.7.tgz", - "integrity": "sha512-5Bo4CrUxrPITrhMKsqUTOkXXo2CoRC5tXxVQhnddCzqDMwRXfyStrxj1oY865g8gaekSBhxAeNkYyUSJvGm9Hw==", + "version": "7.8.11", + "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-7.8.11.tgz", + "integrity": "sha512-ZONFEna6npklSbhDGvCRAdeGMvYwLnVUGfvgZv01zzYoxh5BOsvftROtFl5iozqss5UL8wgJsken6ze7VuHVQg==", "license": "MIT", - "peer": true, "dependencies": { "bson": "^5.5.0", "kareem": "2.5.1", @@ -8473,19 +7457,23 @@ } }, "node_modules/morgan": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz", - "integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==", + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.11.0.tgz", + "integrity": "sha512-zSkVu3t18r39pw4ixfBKvfZi3y2UOqr7d4WYwcj3m8nXpEQK4rPO6GLzs/CExoRgmX3y9EjmmcXqv6jq0SK46g==", "license": "MIT", "dependencies": { "basic-auth": "~2.0.1", "debug": "2.6.9", "depd": "~2.0.0", - "on-finished": "~2.3.0", + "on-finished": "~2.4.1", "on-headers": "~1.1.0" }, "engines": { "node": ">= 0.8.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/morgan/node_modules/debug": { @@ -8503,18 +7491,6 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, - "node_modules/morgan/node_modules/on-finished": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", - "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==", - "license": "MIT", - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, "node_modules/mpath": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.9.0.tgz", @@ -8552,9 +7528,9 @@ } }, "node_modules/napi-postinstall": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.2.4.tgz", - "integrity": "sha512-ZEzHJwBhZ8qQSbknHqYcdtQVr8zUgGyM/q6h6qAyhtyVMNrSgDhrC4disf03dYW0e+czXyLnZINnCTEkWy0eJg==", + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/napi-postinstall/-/napi-postinstall-0.3.4.tgz", + "integrity": "sha512-PHI5f1O0EP5xJ9gQmFGMS6IZcrVvTjpXjz7Na41gTE7eE2hK11lg04CECCYEEjdc17EV4DO+fkGEtt7TpTaTiQ==", "dev": true, "license": "MIT", "bin": { @@ -8614,20 +7590,20 @@ "license": "ISC" }, "node_modules/nice-grpc": { - "version": "2.1.12", - "resolved": "https://registry.npmjs.org/nice-grpc/-/nice-grpc-2.1.12.tgz", - "integrity": "sha512-J1n4Wg+D3IhRhGQb+iqh2OpiM0GzTve/kf2lnlW4S+xczmIEd0aHUDV1OsJ5a3q8GSTqJf+s4Rgg1M8uJltarw==", + "version": "2.1.16", + "resolved": "https://registry.npmjs.org/nice-grpc/-/nice-grpc-2.1.16.tgz", + "integrity": "sha512-Cl3Pn00212Hl8/U6bpgMxmhZj5lyv3nWoJov4cd3FjWarktrMHP4DNvSjCnDwkMWYx4W1tyscEia4JX6Y4GVCQ==", "license": "MIT", "dependencies": { - "@grpc/grpc-js": "^1.13.1", - "abort-controller-x": "^0.4.0", - "nice-grpc-common": "^2.0.2" + "@grpc/grpc-js": "^1.14.0", + "abort-controller-x": "^0.5.0", + "nice-grpc-common": "^2.0.3" } }, "node_modules/nice-grpc-common": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/nice-grpc-common/-/nice-grpc-common-2.0.2.tgz", - "integrity": "sha512-7RNWbls5kAL1QVUOXvBsv1uO0wPQK3lHv+cY1gwkTzirnG1Nop4cBJZubpgziNbaVc/bl9QJcyvsf/NQxa3rjQ==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/nice-grpc-common/-/nice-grpc-common-2.0.3.tgz", + "integrity": "sha512-MEhnD3JMah0mgyivpb9hpRDbOBuXBxI/TVO+OK1h6rC97WM42HsPMR+zzRNQ0C5BqYJTw1nyWiQRD0DucO+pjQ==", "license": "MIT", "dependencies": { "ts-error": "^1.0.6" @@ -8639,6 +7615,35 @@ "integrity": "sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA==", "license": "MIT" }, + "node_modules/node-exports-info": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/node-exports-info/-/node-exports-info-1.6.2.tgz", + "integrity": "sha512-kXs9Go0cah0qHVV2v389IXQLdLCeE1xfFtjOAF+iobu0OIoG1pje8At2vMHyaPMiPMnG/LWP50twML21eMcAag==", + "dev": true, + "license": "MIT", + "dependencies": { + "array.prototype.flatmap": "^1.3.3", + "es-errors": "^1.3.0", + "object.entries": "^1.1.9", + "semver": "^6.3.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/node-exports-info/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/node-fetch": { "version": "2.7.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz", @@ -8823,6 +7828,22 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/object.entries": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.9.tgz", + "integrity": "sha512-8u/hfXFRBD1O0hPUjioLhoWFHRmt6tKA4/vZPyckBr18l1KE9uHrFaFaUi8MDRTpi4uak2goyPTSNJLXX2k2Hw==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.8", + "call-bound": "^1.0.4", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/object.fromentries": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", @@ -9056,9 +8077,9 @@ "license": "MIT" }, "node_modules/path-to-regexp": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", - "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==", + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.13.tgz", + "integrity": "sha512-A/AGNMFN3c8bOlvV9RreMdrv7jsmF9XIfDeCd87+I8RNg6s78BhJxMu69NEMHBSJFxKidViTEdruRwEk/WIKqA==", "license": "MIT" }, "node_modules/performance-now": { @@ -9073,10 +8094,16 @@ "integrity": "sha512-ESj2+eBxhGrcA1azgHs7lARG5+5iLakc/6nlfbpjcLl00HuuUOIuORhYXN4D1HfvMSKuVtFQjAlnwi1JHEeDIw==", "license": "MIT" }, + "node_modules/picocolors": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", + "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==", + "license": "ISC" + }, "node_modules/picomatch": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", - "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.5.tgz", + "integrity": "sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==", "dev": true, "license": "MIT", "engines": { @@ -9127,25 +8154,36 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dev": true, + "license": "MIT", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, "node_modules/protobufjs": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.5.3.tgz", - "integrity": "sha512-sildjKwVqOI2kmFDiXQ6aEB0fjYTafpEvIBs8tOR8qI4spuL9OPROLVu2qZqi/xgCfsHIwVqlaF8JBjWFHnKbw==", + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz", + "integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==", "hasInstallScript": true, "license": "BSD-3-Clause", "dependencies": { "@protobufjs/aspromise": "^1.1.2", "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.4", - "@protobufjs/eventemitter": "^1.1.0", - "@protobufjs/fetch": "^1.1.0", + "@protobufjs/codegen": "^2.0.5", + "@protobufjs/eventemitter": "^1.1.1", + "@protobufjs/fetch": "^1.1.1", "@protobufjs/float": "^1.0.2", - "@protobufjs/inquire": "^1.1.0", "@protobufjs/path": "^1.1.2", "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.0", + "@protobufjs/utf8": "^1.1.1", "@types/node": ">=13.7.0", - "long": "^5.0.0" + "long": "^5.3.2" }, "engines": { "node": ">=12.0.0" @@ -9177,9 +8215,9 @@ } }, "node_modules/pump": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.3.tgz", - "integrity": "sha512-todwxLMY7/heScKmntwQG8CXVkWUOdYxIvY2s0VWAAMh/nd8SoYiRaKjlr7+iCs984f2P8zvrfWcDDYVb73NfA==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.4.tgz", + "integrity": "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==", "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -9196,12 +8234,13 @@ } }, "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", + "version": "6.15.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", + "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", "license": "BSD-3-Clause", "dependencies": { - "side-channel": "^1.0.6" + "es-define-property": "^1.0.1", + "side-channel": "^1.1.1" }, "engines": { "node": ">=0.6" @@ -9210,27 +8249,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/quick-lru": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", @@ -9267,20 +8285,39 @@ } }, "node_modules/raw-body": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", - "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "version": "2.5.3", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.3.tgz", + "integrity": "sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==", "license": "MIT", "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "bytes": "~3.1.2", + "http-errors": "~2.0.1", + "iconv-lite": "~0.4.24", + "unpipe": "~1.0.0" }, "engines": { "node": ">= 0.8" } }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", + "dev": true, + "license": "MIT" + }, "node_modules/readable-stream": { "version": "1.1.14", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", @@ -9394,24 +8431,14 @@ } }, "node_modules/request/node_modules/qs": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", - "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.5.tgz", + "integrity": "sha512-mzR4sElr1bfCaPJe7m8ilJ6ZXdDaGoObcYR0ZHSsktM/Lt21MVHj5De30GQH2eiZ1qGRTO7LCAzQsUeXTNexWQ==", "license": "BSD-3-Clause", "engines": { "node": ">=0.6" } }, - "node_modules/request/node_modules/uuid": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", - "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", - "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", - "license": "MIT", - "bin": { - "uuid": "bin/uuid" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -9422,12 +8449,16 @@ } }, "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "version": "2.0.0-next.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.7.tgz", + "integrity": "sha512-tqt+NBWwyaMgw3zDsnygx4CByWjQEJHOPMdslYhppaQSJUtL/D4JO9CcBBlhPoI8lz9oJIDXkwXfhF4aWqP8xQ==", + "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.16.0", + "es-errors": "^1.3.0", + "is-core-module": "^2.16.2", + "node-exports-info": "^1.6.0", + "object-keys": "^1.1.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -9485,17 +8516,6 @@ "integrity": "sha512-e0dOpjm5DseomnXx2M5lpdZ5zoHqF1+bqdMJUohoYVVQa7cBdnk7fdmeI6byNWP/kiME72EeTiSypTCVnpLiDg==", "license": "MIT" }, - "node_modules/reusify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", - "integrity": "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==", - "dev": true, - "license": "MIT", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, "node_modules/rimraf": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", @@ -9512,40 +8532,16 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, "node_modules/safe-array-concat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", - "integrity": "sha512-AURm5f0jYEOydBj7VQlVvDrjeFgthDdEF5H1dP+6mNpoXOMo1quQqJ4wvJDyRZ9+pO3kGWoOdmV08cSv2aJV6Q==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.4.tgz", + "integrity": "sha512-wtZlHyOje6OZTGqAoaDKxFkgRtkF9CnHAVnCHKfuj200wAgL+bSJhdsCD2l0Qx/2ekEXjPWcyKkfGb5CPboslg==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", - "get-intrinsic": "^1.2.6", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", + "get-intrinsic": "^1.3.0", "has-symbols": "^1.1.0", "isarray": "^2.0.5" }, @@ -9647,9 +8643,9 @@ } }, "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.8.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", + "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -9659,24 +8655,24 @@ } }, "node_modules/send": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz", - "integrity": "sha512-dW41u5VfLXu8SJh5bwRmyYUbAoSB3c9uQh6L8h/KtsFREPWpbX1lrljJo186Jc4nmci/sGUZ9a0a0J2zgfq2hw==", + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/send/-/send-0.19.2.tgz", + "integrity": "sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==", "license": "MIT", "dependencies": { "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", - "encodeurl": "~1.0.2", + "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", + "fresh": "~0.5.2", + "http-errors": "~2.0.1", "mime": "1.6.0", "ms": "2.1.3", - "on-finished": "2.4.1", + "on-finished": "~2.4.1", "range-parser": "~1.2.1", - "statuses": "2.0.1" + "statuses": "~2.0.2" }, "engines": { "node": ">= 0.8.0" @@ -9697,25 +8693,16 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, - "node_modules/send/node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", - "license": "MIT", - "engines": { - "node": ">= 0.8" - } - }, "node_modules/serve-static": { - "version": "1.16.2", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.2.tgz", - "integrity": "sha512-VqpjJZKadQB/PEbEwvFdO43Ax5dFBZ2UECszz8bQ7pi7wt//PWe1P6MN7eCnjsatYtBT6EuiClbjSWP2WrIoTw==", + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.16.3.tgz", + "integrity": "sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==", "license": "MIT", "dependencies": { "encodeurl": "~2.0.0", "escape-html": "~1.0.3", "parseurl": "~1.3.3", - "send": "0.19.0" + "send": "~0.19.1" }, "engines": { "node": ">= 0.8.0" @@ -9812,14 +8799,14 @@ } }, "node_modules/side-channel": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz", - "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", + "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3", - "side-channel-list": "^1.0.0", + "object-inspect": "^1.13.4", + "side-channel-list": "^1.0.1", "side-channel-map": "^1.0.1", "side-channel-weakmap": "^1.0.2" }, @@ -9831,13 +8818,13 @@ } }, "node_modules/side-channel-list": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz", - "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", + "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", "license": "MIT", "dependencies": { "es-errors": "^1.3.0", - "object-inspect": "^1.13.3" + "object-inspect": "^1.13.4" }, "engines": { "node": ">= 0.4" @@ -9921,12 +8908,12 @@ } }, "node_modules/socks": { - "version": "2.8.5", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.5.tgz", - "integrity": "sha512-iF+tNDQla22geJdTyJB1wM/qrX9DMRwWrciEPwWLPRWAUEM8sQiyxgckLxWT1f7+9VabJS0jTGGr4QgBuvi6Ww==", + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.9.tgz", + "integrity": "sha512-LJhUYUvItdQ0LkJTmPeaEObWXAqFyfmP85x0tch/ez9cahmhlBBLbIqDFnvBnUJGagb0JbIQrkBs1wJ+yRYpEw==", "license": "MIT", "dependencies": { - "ip-address": "^9.0.5", + "ip-address": "^10.1.1", "smart-buffer": "^4.2.0" }, "engines": { @@ -9961,12 +8948,6 @@ "memory-pager": "^1.0.2" } }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", - "license": "BSD-3-Clause" - }, "node_modules/sshpk": { "version": "1.18.0", "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.18.0.tgz", @@ -9992,18 +8973,15 @@ "node": ">=0.10.0" } }, - "node_modules/sshpk/node_modules/jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==", - "license": "MIT" - }, - "node_modules/stable-hash": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stable-hash/-/stable-hash-0.0.5.tgz", - "integrity": "sha512-+L3ccpzibovGXFK+Ap/f8LOS0ahMrHTf3xu7mMLSpEGU0EO9ucaysSylKo9eRDFNhWve/y275iPmIZ4z39a9iA==", + "node_modules/stable-hash-x": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/stable-hash-x/-/stable-hash-x-0.2.0.tgz", + "integrity": "sha512-o3yWv49B/o4QZk5ZcsALc6t0+eCelPc44zZsLtCQnZPDwFpDYSWcDnrv2TtMmMbQ7uKo3J0HTURCqckw23czNQ==", "dev": true, - "license": "MIT" + "license": "MIT", + "engines": { + "node": ">=12.0.0" + } }, "node_modules/static-eval": { "version": "2.1.1", @@ -10094,9 +9072,9 @@ } }, "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", + "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", "license": "MIT", "engines": { "node": ">= 0.8" @@ -10160,20 +9138,60 @@ "node": ">=8" } }, - "node_modules/string.prototype.trim": { - "version": "1.2.10", - "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.10.tgz", - "integrity": "sha512-Rs66F0P/1kedk5lyYyH9uBzuiI/kNRmwJAR9quK6VOtIpZ2G+hMZd+HQbbv25MgCA6gEffoMZYxlTod4WcdrKA==", + "node_modules/string.prototype.matchall": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.12.tgz", + "integrity": "sha512-6CC9uyBL+/48dYizRf7H7VAYCMCNTBeM78x/VTUe9bFEaxBepPJDa1Ow99LqI/1yF7kuy7Q3cQsYMrcjGUcskA==", "dev": true, "license": "MIT", "dependencies": { "call-bind": "^1.0.8", - "call-bound": "^1.0.2", + "call-bound": "^1.0.3", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.6", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.6", + "gopd": "^1.2.0", + "has-symbols": "^1.1.0", + "internal-slot": "^1.1.0", + "regexp.prototype.flags": "^1.5.3", + "set-function-name": "^2.0.2", + "side-channel": "^1.1.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.repeat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/string.prototype.repeat/-/string.prototype.repeat-1.0.0.tgz", + "integrity": "sha512-0u/TldDbKD8bFCQ/4f5+mNRrXwZ8hg2w7ZR8wa16e8z9XpePWl3eGEcUD0OXpEH/VJH/2G3gjUtR3ZOiBe2S/w==", + "dev": true, + "license": "MIT", + "dependencies": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "node_modules/string.prototype.trim": { + "version": "1.2.11", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.11.tgz", + "integrity": "sha512-PwvK7BU+CMTJGYQCTZb5RWXIML92lftJLhQz1tBzgKiqGxJaMlBAa48POXaNAC2s4y8jr3EFqrkF9+44neS46w==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", "define-data-property": "^1.1.4", "define-properties": "^1.2.1", - "es-abstract": "^1.23.5", - "es-object-atoms": "^1.0.0", - "has-property-descriptors": "^1.0.2" + "es-abstract": "^1.24.2", + "es-object-atoms": "^1.1.2", + "has-property-descriptors": "^1.0.2", + "safe-regex-test": "^1.1.0" }, "engines": { "node": ">= 0.4" @@ -10183,16 +9201,16 @@ } }, "node_modules/string.prototype.trimend": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.9.tgz", - "integrity": "sha512-G7Ok5C6E/j4SGfyLCloXTrngQIQU3PWtXGst3yM7Bea9FRURf1S42ZHlZZtsNque2FN2PoUhfZXYLNWwEr4dLQ==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.10.tgz", + "integrity": "sha512-2+3aDAOmPTmuFwjDnmJG2ctEkQKVki7vOSqaxkv42Mowj1V6PnvuwFCRrR5lChUux1TBskPjfkeTOhqczDMxTw==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.8", - "call-bound": "^1.0.2", + "call-bind": "^1.0.9", + "call-bound": "^1.0.4", "define-properties": "^1.2.1", - "es-object-atoms": "^1.0.0" + "es-object-atoms": "^1.1.2" }, "engines": { "node": ">= 0.4" @@ -10267,22 +9285,11 @@ "node": ">=12.*" } }, - "node_modules/strnum": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.1.2.tgz", - "integrity": "sha512-vrN+B7DBIoTTZjnPNewwhx6cBA/H+IS7rfW68n7XxC1y7uoiGQBxaKzqucGUgavX15dJgiGztLJ8vxuEzwqBdA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/NaturalIntelligence" - } - ], - "license": "MIT" - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "license": "MIT", "dependencies": { "has-flag": "^4.0.0" @@ -10307,6 +9314,7 @@ "version": "6.2.1", "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", + "deprecated": "Old versions of tar are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me", "license": "ISC", "dependencies": { "chownr": "^2.0.0", @@ -10395,14 +9403,14 @@ } }, "node_modules/tinyglobby": { - "version": "0.2.14", - "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", - "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", + "version": "0.2.17", + "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.17.tgz", + "integrity": "sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==", "dev": true, "license": "MIT", "dependencies": { - "fdir": "^6.4.4", - "picomatch": "^4.0.2" + "fdir": "^6.5.0", + "picomatch": "^4.0.4" }, "engines": { "node": ">=12.0.0" @@ -10422,19 +9430,6 @@ "string-to-arraybuffer": "^1.0.0" } }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -10470,9 +9465,9 @@ } }, "node_modules/ts-api-utils": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.1.0.tgz", - "integrity": "sha512-CUgTZL1irw8u29bzrOD/nH85jqyc74D6SshFgujOIA7osm2Rz7dYH77agkx7H4FBNxDq7Cjf+IjaX/8zwFW+ZQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz", + "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==", "dev": true, "license": "MIT", "engines": { @@ -10565,18 +9560,6 @@ "node": ">= 0.8.0" } }, - "node_modules/type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "license": "(MIT OR CC0-1.0)", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", @@ -10648,18 +9631,18 @@ } }, "node_modules/typed-array-length": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.7.tgz", - "integrity": "sha512-3KS2b+kL7fsuk/eJZ7EQdnEmQoaho/r6KUef7hxvltNA5DR8NAUM+8wJMbJyZ4G9/7i3v5zPBIMN5aybAh2/Jg==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.8.tgz", + "integrity": "sha512-phPGCwqr2+Qo0fwniCE8e4pKnGu/yFb5nD5Y8bf0EEeiI5GklnACYA9GFy/DrAeRrKHXvHn+1SUsOWgJp6RO+g==", "dev": true, "license": "MIT", "dependencies": { - "call-bind": "^1.0.7", - "for-each": "^0.3.3", - "gopd": "^1.0.1", - "is-typed-array": "^1.1.13", - "possible-typed-array-names": "^1.0.0", - "reflect.getprototypeof": "^1.0.6" + "call-bind": "^1.0.9", + "for-each": "^0.3.5", + "gopd": "^1.2.0", + "is-typed-array": "^1.1.15", + "possible-typed-array-names": "^1.1.0", + "reflect.getprototypeof": "^1.0.10" }, "engines": { "node": ">= 0.4" @@ -10679,7 +9662,6 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", "license": "Apache-2.0", - "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -10689,15 +9671,16 @@ } }, "node_modules/typescript-eslint": { - "version": "8.34.1", - "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.34.1.tgz", - "integrity": "sha512-XjS+b6Vg9oT1BaIUfkW3M3LvqZE++rbzAMEHuccCfO/YkP43ha6w3jTEMilQxMF92nVOYCcdjv1ZUhAa1D/0ow==", + "version": "8.64.0", + "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.64.0.tgz", + "integrity": "sha512-0qg+pDNMnqYzqH9AnNK+39tejHvsShUOUUoRUgtnTGE7QuMZhiFDnozq8nHJVq+Wae6NMLKNWLg5WmkcC/ndyQ==", "dev": true, "license": "MIT", "dependencies": { - "@typescript-eslint/eslint-plugin": "8.34.1", - "@typescript-eslint/parser": "8.34.1", - "@typescript-eslint/utils": "8.34.1" + "@typescript-eslint/eslint-plugin": "8.64.0", + "@typescript-eslint/parser": "8.64.0", + "@typescript-eslint/typescript-estree": "8.64.0", + "@typescript-eslint/utils": "8.64.0" }, "engines": { "node": "^18.18.0 || ^20.9.0 || >=21.1.0" @@ -10707,8 +9690,8 @@ "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^8.57.0 || ^9.0.0", - "typescript": ">=4.8.4 <5.9.0" + "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0", + "typescript": ">=4.8.4 <6.1.0" } }, "node_modules/typescript-is": { @@ -10774,38 +9757,41 @@ } }, "node_modules/unrs-resolver": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.9.0.tgz", - "integrity": "sha512-wqaRu4UnzBD2ABTC1kLfBjAqIDZ5YUTr/MLGa7By47JV1bJDSW7jq/ZSLigB7enLe7ubNaJhtnBXgrc/50cEhg==", + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/unrs-resolver/-/unrs-resolver-1.12.2.tgz", + "integrity": "sha512-dmlRxBJJayXjqTwC+JtF1HhJmgf3ftQ3YejFcZrf4+KKtJv0qDsK1pjqaaVjG7wJ5NJ6UVP1OqRMQ71Z4C3rxQ==", "dev": true, "hasInstallScript": true, "license": "MIT", "dependencies": { - "napi-postinstall": "^0.2.2" + "napi-postinstall": "^0.3.4" }, "funding": { "url": "https://opencollective.com/unrs-resolver" }, "optionalDependencies": { - "@unrs/resolver-binding-android-arm-eabi": "1.9.0", - "@unrs/resolver-binding-android-arm64": "1.9.0", - "@unrs/resolver-binding-darwin-arm64": "1.9.0", - "@unrs/resolver-binding-darwin-x64": "1.9.0", - "@unrs/resolver-binding-freebsd-x64": "1.9.0", - "@unrs/resolver-binding-linux-arm-gnueabihf": "1.9.0", - "@unrs/resolver-binding-linux-arm-musleabihf": "1.9.0", - "@unrs/resolver-binding-linux-arm64-gnu": "1.9.0", - "@unrs/resolver-binding-linux-arm64-musl": "1.9.0", - "@unrs/resolver-binding-linux-ppc64-gnu": "1.9.0", - "@unrs/resolver-binding-linux-riscv64-gnu": "1.9.0", - "@unrs/resolver-binding-linux-riscv64-musl": "1.9.0", - "@unrs/resolver-binding-linux-s390x-gnu": "1.9.0", - "@unrs/resolver-binding-linux-x64-gnu": "1.9.0", - "@unrs/resolver-binding-linux-x64-musl": "1.9.0", - "@unrs/resolver-binding-wasm32-wasi": "1.9.0", - "@unrs/resolver-binding-win32-arm64-msvc": "1.9.0", - "@unrs/resolver-binding-win32-ia32-msvc": "1.9.0", - "@unrs/resolver-binding-win32-x64-msvc": "1.9.0" + "@unrs/resolver-binding-android-arm-eabi": "1.12.2", + "@unrs/resolver-binding-android-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-arm64": "1.12.2", + "@unrs/resolver-binding-darwin-x64": "1.12.2", + "@unrs/resolver-binding-freebsd-x64": "1.12.2", + "@unrs/resolver-binding-linux-arm-gnueabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm-musleabihf": "1.12.2", + "@unrs/resolver-binding-linux-arm64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-arm64-musl": "1.12.2", + "@unrs/resolver-binding-linux-loong64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-loong64-musl": "1.12.2", + "@unrs/resolver-binding-linux-ppc64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-riscv64-musl": "1.12.2", + "@unrs/resolver-binding-linux-s390x-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-gnu": "1.12.2", + "@unrs/resolver-binding-linux-x64-musl": "1.12.2", + "@unrs/resolver-binding-openharmony-arm64": "1.12.2", + "@unrs/resolver-binding-wasm32-wasi": "1.12.2", + "@unrs/resolver-binding-win32-arm64-msvc": "1.12.2", + "@unrs/resolver-binding-win32-ia32-msvc": "1.12.2", + "@unrs/resolver-binding-win32-x64-msvc": "1.12.2" } }, "node_modules/untildify": { @@ -10843,22 +9829,19 @@ } }, "node_modules/uuid": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", - "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", - "funding": [ - "https://github.com/sponsors/broofa", - "https://github.com/sponsors/ctavan" - ], + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028).", "license": "MIT", "bin": { - "uuid": "dist/bin/uuid" + "uuid": "bin/uuid" } }, "node_modules/validator": { - "version": "13.15.15", - "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.15.tgz", - "integrity": "sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A==", + "version": "13.15.35", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.15.35.tgz", + "integrity": "sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==", "license": "MIT", "engines": { "node": ">= 0.10" @@ -11006,14 +9989,14 @@ } }, "node_modules/which-typed-array": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.19.tgz", - "integrity": "sha512-rEvr90Bck4WZt9HHFC4DJMsjvu7x+r6bImz0/BrbWb7A2djJ8hnZMrWnHo9F8ssv0OMErasDhftrfROTyqSDrw==", + "version": "1.1.22", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.22.tgz", + "integrity": "sha512-fvO4ExWMFsqyhG3AiPAObMuY1lxaqgYcxbc49CNdWDDECOJNgQyvsOWVwbZc+qf3rzRtxojBK+CMEv0Ld5CYpw==", "dev": true, "license": "MIT", "dependencies": { "available-typed-arrays": "^1.0.7", - "call-bind": "^1.0.8", + "call-bind": "^1.0.9", "call-bound": "^1.0.4", "for-each": "^0.3.5", "get-proto": "^1.0.1", @@ -11113,9 +10096,9 @@ "license": "ISC" }, "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "version": "16.2.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.2.tgz", + "integrity": "sha512-Nt9ZJjXTv5R8MHbqby/wXQ6Gi0Bb3TcYZkR1bzuL4yB2OxWPkXknz513gEF0GoA6tn00UpbPvERW8rzCuWCA6w==", "dev": true, "license": "MIT", "dependencies": { @@ -11169,9 +10152,9 @@ } }, "node_modules/yoctocolors-cjs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.2.tgz", - "integrity": "sha512-cYVsTjKl8b+FrnidjibDWskAv7UKOfcwaVZdp/it9n1s9fU3IkgDbhdIRKCW4JDsAlECJY0ytoVPT3sK6kideA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/yoctocolors-cjs/-/yoctocolors-cjs-2.1.3.tgz", + "integrity": "sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==", "license": "MIT", "engines": { "node": ">=18" @@ -11181,9 +10164,9 @@ } }, "node_modules/zod": { - "version": "3.25.67", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.67.tgz", - "integrity": "sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw==", + "version": "3.25.76", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.25.76.tgz", + "integrity": "sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==", "license": "MIT", "funding": { "url": "https://github.com/sponsors/colinhacks" diff --git a/package.json b/package.json index 8e844b4..7a7a7e2 100644 --- a/package.json +++ b/package.json @@ -4,8 +4,8 @@ "description": "", "main": "./dist/server.js", "scripts": { - "lint": "eslint .", - "lint:fix": "eslint --fix .", + "lint": "eslint ./src", + "lint:fix": "eslint --fix ./src", "download-geoip-db": "node ./scripts/download-ip2location-databases.js", "build": "npm run lint && npm run clean && npx tsc && npx tsc-alias && npm run copy-static && npm run download-geoip-db", "clean": "rimraf ./dist", @@ -28,12 +28,13 @@ "@aws-sdk/client-s3": "^3.657.0", "@aws-sdk/client-ses": "^3.515.0", "@inquirer/prompts": "^7.2.0", - "@pretendonetwork/grpc": "^2.2.3", + "@pretendonetwork/grpc": "^2.5.4", "bcrypt": "^5.0.0", "buffer-crc32": "^0.2.13", "colors": "^1.4.0", "cors": "^2.8.5", "crc": "^4.3.2", + "cron": "^4.4.0", "dicer": "^0.2.5", "dotenv": "^16.0.3", "ejs": "^3.1.10", @@ -47,7 +48,6 @@ "image-pixels": "^1.1.1", "ip2location-nodejs": "^9.6.3", "is-valid-hostname": "^1.0.2", - "joi": "^17.8.3", "mii-js": "github:PretendoNetwork/mii-js#f1741e1f82771dd7c753fd408230373d33caa184", "moment": "^2.29.4", "mongoose": "^7.0.0", @@ -68,7 +68,7 @@ }, "devDependencies": { "@hcaptcha/types": "^1.0.3", - "@pretendonetwork/eslint-config": "^0.0.8", + "@pretendonetwork/eslint-config": "^0.1.4", "@types/bcrypt": "^5.0.0", "@types/buffer-crc32": "^0.2.2", "@types/cors": "^2.8.13", @@ -89,5 +89,8 @@ "globals": "^15.14.0", "ndarray": "^1.0.19", "typescript": "^4.9.5" + }, + "overrides": { + "@bufbuild/protobuf": "2.2.2" } } diff --git a/src/database.ts b/src/database.ts index 3e31e8a..7c56771 100644 --- a/src/database.ts +++ b/src/database.ts @@ -1,7 +1,8 @@ +import crypto from 'node:crypto'; import mongoose from 'mongoose'; import bcrypt from 'bcrypt'; -import joi from 'joi'; -import { nintendoPasswordHash, decryptToken, unpackToken } from '@/util'; +import { nintendoPasswordHash } from '@/util'; +import { OAuthToken } from '@/models/oauth-token'; import { PNID } from '@/models/pnid'; import { Server } from '@/models/server'; import { LOG_ERROR } from '@/logger'; @@ -12,18 +13,10 @@ import type { HydratedPNIDDocument } from '@/types/mongoose/pnid'; import type { IDeviceAttribute } from '@/types/mongoose/device-attribute'; import type { HydratedServerDocument } from '@/types/mongoose/server'; import type { PNIDProfile } from '@/types/services/nnas/pnid-profile'; -import type { ConnectionData } from '@/types/services/api/connection-data'; -import type { ConnectionResponse } from '@/types/services/api/connection-response'; -import type { DiscordConnectionData } from '@/types/services/api/discord-connection-data'; const connection_string = config.mongoose.connection_string; const options = config.mongoose.options; -// TODO - Extend this later with more settings -const discordConnectionSchema = joi.object({ - id: joi.string() -}); - const accessModeOrder: Record = { prod: ['prod'], test: ['test', 'prod'], @@ -110,26 +103,37 @@ async function getPNIDByOAuthToken(token: string, expectedSystemType: SystemType verifyConnected(); try { - const decryptedToken = decryptToken(Buffer.from(token, 'hex')); - const unpackedToken = unpackToken(decryptedToken); + const oauthToken = await OAuthToken.findOne({ + token: crypto.createHash('sha256').update(token).digest('hex') + }); - if (unpackedToken.system_type !== expectedSystemType) { - return null; - } - if (unpackedToken.token_type !== expectedTokenType) { + if (!oauthToken) { return null; } - const pnid = await getPNIDByPID(unpackedToken.pid); + if (oauthToken.info.system_type !== expectedSystemType) { + return null; + } + + if (oauthToken.info.token_type !== expectedTokenType) { + return null; + } + + const pnid = await getPNIDByPID(oauthToken.pid); if (pnid) { - const expireTime = Math.floor((Number(unpackedToken.expire_time) / 1000)); + const expireTime = Math.floor((Number(oauthToken.info.expires) / 1000)); if (Math.floor(Date.now() / 1000) > expireTime) { return null; } } + // * Refresh tokens are single use + if (expectedTokenType === TokenType.OAuthRefresh) { + await oauthToken.deleteOne(); + } + return pnid; } catch (error: any) { // TODO - Handle error @@ -291,51 +295,20 @@ export async function getServerByClientID(clientID: string, accessMode: string): return null; } -export async function addPNIDConnection(pnid: HydratedPNIDDocument, data: ConnectionData, type: string): Promise { - if (type === 'discord') { - return await addPNIDConnectionDiscord(pnid, data); - } -} - -export async function addPNIDConnectionDiscord(pnid: HydratedPNIDDocument, data: DiscordConnectionData): Promise { - const valid = discordConnectionSchema.validate(data); - - if (valid.error) { - return { - app: 'api', - status: 400, - error: 'Invalid or missing connection data' - }; - } - - await PNID.updateOne({ pid: pnid.pid }, { - $set: { - 'connections.discord.id': data.id +export async function checkMarkedDeletions(): Promise { + const pnids = await PNID.find({ + marked_for_deletion: true, + deleted: false, + hard_delete_time: { + $lte: new Date() } }); - return { - app: 'api', - status: 200 - }; -} - -export async function removePNIDConnection(pnid: HydratedPNIDDocument, type: string): Promise { - // * Add more connections later? - if (type === 'discord') { - return await removePNIDConnectionDiscord(pnid); + for (const pnid of pnids) { + try { + await pnid.scrub(); + } catch (error) { + LOG_ERROR(`Failed to scrub PNID ${pnid.pid}: ${error}`); + } } } - -export async function removePNIDConnectionDiscord(pnid: HydratedPNIDDocument): Promise { - await PNID.updateOne({ pid: pnid.pid }, { - $set: { - 'connections.discord.id': '' - } - }); - - return { - app: 'api', - status: 200 - }; -} diff --git a/src/middleware/api.ts b/src/middleware/api.ts index 1e93547..cbb3250 100644 --- a/src/middleware/api.ts +++ b/src/middleware/api.ts @@ -2,6 +2,7 @@ import { getValueFromHeaders } from '@/util'; import { getPNIDByAPIAccessToken } from '@/database'; import { LOG_ERROR } from '@/logger'; import type express from 'express'; + async function APIMiddleware(request: express.Request, _response: express.Response, next: express.NextFunction): Promise { const authHeader = getValueFromHeaders(request.headers, 'authorization'); diff --git a/src/middleware/nasc.ts b/src/middleware/nasc.ts index 944e9e8..7b0d860 100644 --- a/src/middleware/nasc.ts +++ b/src/middleware/nasc.ts @@ -6,10 +6,10 @@ import { connection as databaseConnection } from '@/database'; import NintendoCertificate from '@/nintendo-certificate'; import { LOG_ERROR } from '@/logger'; import type express from 'express'; -import type { NASCRequestParams } from '@/types/services/nasc/request-params'; +import type { NASCACRequestParams } from '@/types/services/nasc/ac-request-params'; async function NASCMiddleware(request: express.Request, response: express.Response, next: express.NextFunction): Promise { - const requestParams: NASCRequestParams = request.body; + const requestParams: NASCACRequestParams = request.body; if (!requestParams.action || !requestParams.fcdcert || @@ -37,15 +37,15 @@ async function NASCMiddleware(request: express.Request, response: express.Respon let pidHmac = ''; let password = ''; - if (requestParams.userid) { + if ('userid' in requestParams) { pid = Number(nintendoBase64Decode(requestParams.userid).toString()); } - if (requestParams.uidhmac) { + if ('uidhmac' in requestParams) { pidHmac = nintendoBase64Decode(requestParams.uidhmac).toString(); } - if (requestParams.passwd) { + if ('passwd' in requestParams) { password = nintendoBase64Decode(requestParams.passwd).toString(); } @@ -232,31 +232,27 @@ async function NASCMiddleware(request: express.Request, response: express.Respon return next(); } -// * https://www.adminsub.net/mac-address-finder/nintendo +// * https://standards-oui.ieee.org // * Saves us from doing an OUI lookup each time const NINTENDO_VENDER_OUIS = [ - 'ECC40D', 'E84ECE', 'E0F6B5', 'E0E751', 'E00C7F', 'DC68EB', - 'D86BF7', 'D4F057', 'CCFB65', 'CC9E00', 'B8AE6E', 'B88AEC', - 'B87826', 'A4C0E1', 'A45C27', 'A438CC', '9CE635', '98E8FA', - '98B6E9', '98415C', '9458CB', '8CCDE8', '8C56C5', '7CBB8A', - '78A2A0', '7048F7', '64B5C6', '606BFF', '5C521E', '58BDA3', - '582F40', '48A5E7', '40F407', '40D28A', '34AF2C', '342FBD', - '2C10C1', '182A7B', '0403D6', '002709', '002659', '0025A0', - '0024F3', '002444', '00241E', '0023CC', '002331', '0022D7', - '0022AA', '00224C', '0021BD', '002147', '001FC5', '001F32', - '001EA9', '001E35', '001DBC', '001CBE', '001BEA', '001B7A', - '001AE9', '0019FD', '00191D', '0017AB', '001656', '0009BF', - 'ECC40D', 'E84ECE', 'E0F6B5', 'E0E751', 'E00C7F', 'DC68EB', - 'D86BF7', 'D4F057', 'CCFB65', 'CC9E00', 'B8AE6E', 'B88AEC', - 'B87826', 'A4C0E1', 'A45C27', 'A438CC', '9CE635', '98E8FA', - '98B6E9', '98415C', '9458CB', '8CCDE8', '8C56C5', '7CBB8A', - '78A2A0', '7048F7', '64B5C6', '606BFF', '5C521E', '58BDA3', - '582F40', '48A5E7', '40F407', '40D28A', '34AF2C', '342FBD', - '2C10C1', '182A7B', '0403D6', '002709', '002659', '0025A0', - '0024F3', '002444', '00241E', '0023CC', '002331', '0022D7', - '0022AA', '00224C', '0021BD', '002147', '001FC5', '001F32', - '001EA9', '001E35', '001DBC', '001CBE', '001BEA', '001B7A', - '001AE9', '0019FD', '00191D', '0017AB', '001656', '0009BF' + '601AC7', 'BC9EBB', 'CC5B31', '1C4586', 'E8A0CD', '702C09', + '7048F7', '98E8FA', 'ECC40D', '606BFF', '64B5C6', '40D28A', + 'A45C27', '8C56C5', '002659', '00241E', '002444', '98E255', + 'E0EFBF', '948E6D', '38C6CE', 'C89143', 'DCCD18', '28CF51', + '58B03E', '200BCF', '748469', '70F088', '9458CB', '582F40', + 'B88AEC', 'A438CC', '40F407', 'A4C0E1', '0022D7', '001CBE', + '001B7A', '001AE9', '0009BF', '904528', 'ACFAE4', 'BC89A6', + '201C3A', '7820A5', 'E0F6B5', '342FBD', '98415C', 'D4F057', + '5C521E', '98B6E9', 'CCFB65', 'B8AE6E', '182A7B', '2C10C1', + '002331', '001E35', '001BEA', '0017AB', '001656', 'BC744B', + '3CA9AB', 'C84805', 'C0A4CF', '3089EC', '483177', '50236D', + 'D05509', 'E8DA20', '7CBB8A', '34AF2C', '78A2A0', 'E84ECE', + '002709', '0025A0', '0024F3', '0023CC', '001F32', '001EA9', + '001DBC', '0019FD', '00191D', 'A4C1E8', 'D86B83', '4044F7', + 'B86870', 'BCCE25', '80D2E5', '5C0CE6', '74F9CA', '48A5E7', + 'B87826', 'DC68EB', '0403D6', '9CE635', '8CCDE8', '58BDA3', + 'E00C7F', 'CC9E00', 'D86BF7', 'E0E751', '0022AA', '00224C', + '0021BD', '002147', '001FC5', '48F1EB', '78818C', '4C306A' ]; // TODO - Make something better diff --git a/src/middleware/pnid.ts b/src/middleware/pnid.ts index 55ae114..9740114 100644 --- a/src/middleware/pnid.ts +++ b/src/middleware/pnid.ts @@ -53,7 +53,7 @@ async function PNIDMiddleware(request: express.Request, response: express.Respon return; } - if (pnid.deleted) { + if (pnid.deleted || pnid.marked_for_deletion) { response.status(400).send(xmlbuilder.create({ errors: { error: { diff --git a/src/middleware/ratelimit.ts b/src/middleware/ratelimit.ts index 99a1698..aafe089 100644 --- a/src/middleware/ratelimit.ts +++ b/src/middleware/ratelimit.ts @@ -1,9 +1,9 @@ import crypto from 'node:crypto'; import ratelimit from 'express-rate-limit'; -import { getValueFromHeaders } from '@/util'; +import { getValueFromHeaders, nascError } from '@/util'; import type express from 'express'; -export default ratelimit({ +export const deviceRatelimit = ratelimit({ windowMs: 60 * 1000, max: 1, keyGenerator: (request: express.Request): string => { @@ -16,3 +16,50 @@ export default ratelimit({ return crypto.createHash('md5').update(data!).digest('hex'); } }); + +export const loginRatelimit = ratelimit({ + windowMs: 5 * 60 * 1000, // 5mins + max: 20, + keyGenerator: (request: express.Request): string => { + const grantType = request.body?.grant_type; + const username = request.body?.username?.trim(); + const refreshToken = request.body?.refresh_token?.trim(); + + let data = request.ip; + // Mix in user identification to make CGNAT less harsh + if (grantType == 'password') { + data += String(username); + } else if (grantType == 'refresh_token') { + data += String(refreshToken); + } + + return crypto.createHash('md5').update(data!).digest('hex'); + } +}); + +export const webRegisterRatelimit = ratelimit({ + windowMs: 60 * 1000, + max: 5, // lax for CGNAT + keyGenerator: (request: express.Request): string => { + const data = request.body.ip?.trim(); // forwarded from web + + return crypto.createHash('md5').update(data!).digest('hex'); + } +}); + +export const passwordResetRatelimit = ratelimit({ + windowMs: 60 * 1000, + max: 10 // lax for CGNAT +}); + +export const nascRatelimit = ratelimit({ + windowMs: 5 * 60 * 1000, // 5mins + max: 30, + keyGenerator: (request: express.Request): string => { + const nexAccount = request.nexAccount; + const pid = nexAccount?.pid ?? 0; + + return String(pid); + }, + message: nascError('null') +}); diff --git a/src/models/independent-service-token.ts b/src/models/independent-service-token.ts new file mode 100644 index 0000000..de4e93b --- /dev/null +++ b/src/models/independent-service-token.ts @@ -0,0 +1,45 @@ +import { Schema, model } from 'mongoose'; +import type { Model, HydratedDocument } from 'mongoose'; + +// TODO - Move these to the types folder, just putting them here to push this out the door +export interface IIndependentServiceToken { + token: string; + client_id: string; + title_id: string; + pid: number; + info: { + system_type: number; + token_type: number; + title_id: bigint; + issued: Date; + expires: Date; + }; +} + +export interface IIndependentServiceTokenMethods {} + +interface IIndependentServiceTokenQueryHelpers {} + +export interface IndependentServiceTokenModel extends Model {} + +export type HydratedIndependentServiceTokenDocument = HydratedDocument; + +const IndependentServiceTokenSchema = new Schema({ + token: String, + client_id: String, + title_id: String, + pid: Number, + info: { + system_type: Number, + token_type: Number, + title_id: BigInt, + issued: Date, + expires: Date + } +}); + +IndependentServiceTokenSchema.index({ 'info.expires': 1 }, { expireAfterSeconds: 0 }); +IndependentServiceTokenSchema.index({ token: 1 }); +IndependentServiceTokenSchema.index({ pid: 1 }); + +export const IndependentServiceToken = model('IndependentServiceToken', IndependentServiceTokenSchema); diff --git a/src/models/nex-token.ts b/src/models/nex-token.ts new file mode 100644 index 0000000..feb7273 --- /dev/null +++ b/src/models/nex-token.ts @@ -0,0 +1,43 @@ +import { Schema, model } from 'mongoose'; +import type { Model, HydratedDocument } from 'mongoose'; + +// TODO - Move these to the types folder, just putting them here to push this out the door +export interface INEXToken { + token: string; + game_server_id: string; + pid: number; + info: { + system_type: number; + token_type: number; + title_id: bigint; + issued: Date; + expires: Date; + }; +} + +export interface INEXTokenMethods {} + +interface INEXTokenQueryHelpers {} + +export interface NEXTokenModel extends Model {} + +export type HydratedNEXTokenDocument = HydratedDocument; + +const NEXTokenSchema = new Schema({ + token: String, + game_server_id: String, + pid: Number, + info: { + system_type: Number, + token_type: Number, + title_id: BigInt, + issued: Date, + expires: Date + } +}); + +NEXTokenSchema.index({ 'info.expires': 1 }, { expireAfterSeconds: 0 }); +NEXTokenSchema.index({ token: 1 }); +NEXTokenSchema.index({ pid: 1 }); + +export const NEXToken = model('NEXToken', NEXTokenSchema); diff --git a/src/models/oauth-token.ts b/src/models/oauth-token.ts new file mode 100644 index 0000000..62733b2 --- /dev/null +++ b/src/models/oauth-token.ts @@ -0,0 +1,45 @@ +import { Schema, model } from 'mongoose'; +import type { Model, HydratedDocument } from 'mongoose'; + +// TODO - Move these to the types folder, just putting them here to push this out the door +export interface IOAuthToken { + token: string; + client_id: string; + client_secret: string; + pid: number; + info: { + system_type: number; + token_type: number; + title_id: bigint; + issued: Date; + expires: Date; + }; +} + +export interface IOAuthTokenMethods {} + +interface IOAuthTokenQueryHelpers {} + +export interface OAuthTokenModel extends Model {} + +export type HydratedOAuthTokenDocument = HydratedDocument; + +const OAuthTokenSchema = new Schema({ + token: String, + client_id: String, + client_secret: String, + pid: Number, + info: { + system_type: Number, + token_type: Number, + title_id: BigInt, + issued: Date, + expires: Date + } +}); + +OAuthTokenSchema.index({ 'info.expires': 1 }, { expireAfterSeconds: 0 }); +OAuthTokenSchema.index({ token: 1 }); +OAuthTokenSchema.index({ pid: 1 }); + +export const OAuthToken = model('OAuthToken', OAuthTokenSchema); diff --git a/src/models/password-reset-token.ts b/src/models/password-reset-token.ts new file mode 100644 index 0000000..53c2a44 --- /dev/null +++ b/src/models/password-reset-token.ts @@ -0,0 +1,41 @@ +import { Schema, model } from 'mongoose'; +import type { Model, HydratedDocument } from 'mongoose'; + +// TODO - Move these to the types folder, just putting them here to push this out the door +export interface IPasswordResetToken { + token: string; + pid: number; + info: { + system_type: number; + token_type: number; + title_id: bigint; + issued: Date; + expires: Date; + }; +} + +export interface IPasswordResetTokenMethods {} + +interface IPasswordResetTokenQueryHelpers {} + +export interface PasswordResetTokenModel extends Model {} + +export type HydratedPasswordResetTokenDocument = HydratedDocument; + +const PasswordResetTokenSchema = new Schema({ + token: String, + pid: Number, + info: { + system_type: Number, + token_type: Number, + title_id: BigInt, + issued: Date, + expires: Date + } +}); + +PasswordResetTokenSchema.index({ 'info.expires': 1 }, { expireAfterSeconds: 0 }); +PasswordResetTokenSchema.index({ token: 1 }); +PasswordResetTokenSchema.index({ pid: 1 }); + +export const PasswordResetToken = model('PasswordResetToken', PasswordResetTokenSchema); diff --git a/src/models/pnid.ts b/src/models/pnid.ts index 9311484..e15dcf8 100644 --- a/src/models/pnid.ts +++ b/src/models/pnid.ts @@ -12,6 +12,10 @@ import { DeviceSchema } from '@/models/device'; import { uploadCDNAsset } from '@/util'; import { LOG_ERROR, LOG_WARN } from '@/logger'; import { config } from '@/config-manager'; +import { IndependentServiceToken } from '@/models/independent-service-token'; +import { NEXToken } from '@/models/nex-token'; +import { OAuthToken } from '@/models/oauth-token'; +import { PasswordResetToken } from '@/models/password-reset-token'; import type { IPNID, IPNIDMethods, PNIDModel } from '@/types/mongoose/pnid'; import type { PNIDPermissionFlag } from '@/types/common/permission-flags'; @@ -33,6 +37,11 @@ const PNIDSchema = new Schema({ type: Boolean, default: false }, + marked_for_deletion: { + type: Boolean, + default: false + }, + hard_delete_time: Date, permissions: { type: BigInt, default: 0n @@ -125,6 +134,11 @@ const PNIDSchema = new Schema({ } }, { id: false }); +PNIDSchema.index({ pid: 1 }); +PNIDSchema.index({ usernameLower: 1 }); +// Used for the admin panel querying +PNIDSchema.index({ 'pid': 1, 'username': 1, 'connections.discord.id': 1 }); + PNIDSchema.plugin(uniqueValidator, { message: '{PATH} already in use.' }); /* @@ -225,6 +239,39 @@ PNIDSchema.method('generateMiiImages', async function generateMiiImages(): Promi await uploadCDNAsset(config.s3.bucket, `${userMiiKey}/body.png`, miiStudioBodyImageData, 'public-read'); }); +PNIDSchema.method('markForDeletion', async function markForDeletion() { + this.marked_for_deletion = true; + this.hard_delete_time = new Date(Date.now() + (7 * 24 * 3600 * 1000)); // * 7 day grace period + + if (this.connections?.stripe?.subscription_id) { + const subscriptionID = this.connections.stripe.subscription_id; + + try { + if (stripe) { + // * If a user has an active subscription when they mark themselves for deletion, then they + // * may get charged again in those 7 days while not having access to their account. To prevent + // * that, just update the subscription to cancel at the end of the period. That way the charge + // * doesn't happen, and the user likely won't be restoring their account anyway. If they do + // * restore the account and do want their subscription back then they can create a new one + // * after this one expires which is effectively the same as the old subscription renewing. + // * Pausing collection is another option however it requires much more effort on our end to + // * properly resume the paused charges and recitify any missed ones to prevent invoices + // * from being skipped. This method is just way easier for us to deal with right now, at the + // * expense of making the user do a tad more work on their end + await stripe.subscriptions.update(subscriptionID, { + cancel_at_period_end: true + }); + } else { + LOG_WARN(`UPDATING SUBSCRIPTION FOR USER ${this.username}. HAS STRIPE DATA UDER ID ${this.connections.stripe.customer_id}, BUT STRIPE CLIENT NOT ENABLED.`); + } + } catch (error) { + LOG_ERROR(`ERROR UPDATING SUBSCRIPTION FOR USER ${this.username} (${subscriptionID}). ${error}`); + } + } + + await this.save(); +}); + PNIDSchema.method('scrub', async function scrub() { // * Remove all personal info from a PNID // * Username and PID remain so thye do not get assigned again @@ -287,7 +334,10 @@ PNIDSchema.method('scrub', async function scrub() { }); this.deleted = true; - this.access_level = 0; + this.marked_for_deletion = false; + if (this.access_level > 0) { + this.access_level = 0; + } this.server_access_level = 'prod'; this.creation_date = ''; this.birthdate = ''; @@ -318,6 +368,17 @@ PNIDSchema.method('scrub', async function scrub() { this.connections.stripe.tier_level = 0; this.connections.stripe.tier_name = ''; this.connections.stripe.latest_webhook_timestamp = 0; + + await this.save(); +}); + +PNIDSchema.method('removeAllTokens', async function removeAllTokens() { + await Promise.all([ + IndependentServiceToken.deleteMany({ pid: this.pid }), + NEXToken.deleteMany({ pid: this.pid }), + OAuthToken.deleteMany({ pid: this.pid }), + PasswordResetToken.deleteMany({ pid: this.pid }) + ]); }); PNIDSchema.method('hasPermission', function hasPermission(flag: PNIDPermissionFlag): boolean { diff --git a/src/models/server.ts b/src/models/server.ts index 65f14ea..1a19b4d 100644 --- a/src/models/server.ts +++ b/src/models/server.ts @@ -98,19 +98,24 @@ ServerSchema.method('getServerConnectInfo', async function (): Promise healthCheck(target))) - ]); + // * If the server only has 1 IP, healthCheckTargets will be empty and Promise.race + // * will never resolve. In those cases, just skip this step entirely since we'd + // * have to use that singular IP regardless + if (healthCheckTargets.length !== 0) { + // * Check the random IP and start the race at the same time, preferring + // * the result of the random IP should it succeed. Worst case scenario + // * this takes 2 seconds to complete + const [randomResult, raceResult] = await Promise.allSettled([ + healthCheck({ host: randomIP, port: this.health_check_port! }), + Promise.race(healthCheckTargets.map(target => healthCheck(target))) + ]); - if (randomResult.status === 'rejected') { - if (raceResult.status === 'fulfilled') { - target = raceResult.value; - } else { - LOG_WARN(`Server ${this.service_name} failed to find healthy NEX server. Using the randomly selected IP ${target}`); + if (randomResult.status === 'rejected') { + if (raceResult.status === 'fulfilled') { + target = raceResult.value; + } else { + LOG_WARN(`Server ${this.service_name} failed to find healthy NEX server. Using the randomly selected IP ${target}`); + } } } diff --git a/src/provisioning.ts b/src/provisioning.ts index 1bfe597..b12806b 100644 --- a/src/provisioning.ts +++ b/src/provisioning.ts @@ -1,22 +1,24 @@ import fs from 'node:fs/promises'; import { z } from 'zod'; import mongoose from 'mongoose'; -import { config, disabledFeatures } from './config-manager'; -import { LOG_INFO, LOG_WARN } from './logger'; -import { Server } from './models/server'; +import { config, disabledFeatures } from '@/config-manager'; +import { LOG_INFO, LOG_WARN } from '@/logger'; +import { Server } from '@/models/server'; // Provisioning has a couple edgecases: // - It will only update existing entries, will not add new one // - Only the fields in the below schema will be updated +// - Set fields to null to unset them. Undefined means it won't be modified const serverProvisioningSchema = z.object({ servers: z.array(z.object({ id: z.string(), - name: z.string(), - ip: z.string().optional(), - ipList: z.array(z.string()).optional(), - port: z.coerce.number(), - health_check_port: z.coerce.number().optional() + name: z.string().optional(), + ip: z.string().nullable().optional(), + ip_list: z.array(z.string()).optional(), + port: z.number().optional(), + health_check_port: z.number().nullable().optional(), + aes_key: z.string().optional() })) }); @@ -42,10 +44,11 @@ export async function handleServerProvisioning(): Promise { $set: { _id: id, service_name: server.name, - ipList: server.ipList, + ip_list: server.ip_list, ip: server.ip, port: server.port, - health_check_port: server.health_check_port + health_check_port: server.health_check_port, + aes_key: server.aes_key } }); if (!result) { diff --git a/src/server.ts b/src/server.ts index cd48ace..0914cd8 100644 --- a/src/server.ts +++ b/src/server.ts @@ -3,9 +3,9 @@ import morgan from 'morgan'; import xmlbuilder from 'xmlbuilder'; import xmlparser from '@/middleware/xml-parser'; import { connect as connectCache } from '@/cache'; -import { connect as connectDatabase } from '@/database'; +import { checkMarkedDeletions, connect as connectDatabase } from '@/database'; import { startGRPCServer } from '@/services/grpc/server'; -import { fullUrl, getValueFromHeaders } from '@/util'; +import { fullUrl, getValueFromHeaders, setupScheduledTasks } from '@/util'; import { LOG_INFO, LOG_SUCCESS, LOG_WARN } from '@/logger'; import conntest from '@/services/conntest'; import cbvc from '@/services/cbvc'; @@ -16,7 +16,7 @@ import api from '@/services/api'; import localcdn from '@/services/local-cdn'; import assets from '@/services/assets'; import { config, disabledFeatures } from '@/config-manager'; -import { startProvisioner } from './provisioning'; +import { startProvisioner } from '@/provisioning'; process.title = 'Pretendo - Account'; process.on('uncaughtException', (err, origin) => { @@ -116,6 +116,10 @@ async function main(): Promise { startProvisioner(); + await checkMarkedDeletions(); + + setupScheduledTasks(); + app.listen(config.http.port, () => { LOG_SUCCESS(`HTTP server started on port ${config.http.port}`); }); diff --git a/src/services/api/index.ts b/src/services/api/index.ts index 9420158..2e7e90f 100644 --- a/src/services/api/index.ts +++ b/src/services/api/index.ts @@ -16,7 +16,6 @@ api.options('*', cors()); // * Setup routes LOG_INFO('[USER API] Applying imported routes'); -api.use('/v1/connections', V1.CONNECTIONS); api.use('/v1/email', V1.EMAIL); api.use('/v1/forgot-password', V1.FORGOT_PASSWORD); api.use('/v1/login', V1.LOGIN); diff --git a/src/services/api/routes/index.ts b/src/services/api/routes/index.ts index de8208b..6aafa62 100644 --- a/src/services/api/routes/index.ts +++ b/src/services/api/routes/index.ts @@ -1,4 +1,3 @@ -import connections_v1 from '@/services/api/routes/v1/connections'; import email_v1 from '@/services/api/routes/v1/email'; import forgotPassword_v1 from '@/services/api/routes/v1/forgotPassword'; import login_v1 from '@/services/api/routes/v1/login'; @@ -7,7 +6,6 @@ import resetPassword_v1 from '@/services/api/routes/v1/resetPassword'; import user_v1 from '@/services/api/routes/v1/user'; export const V1 = { - CONNECTIONS: connections_v1, EMAIL: email_v1, FORGOT_PASSWORD: forgotPassword_v1, LOGIN: login_v1, diff --git a/src/services/api/routes/v1/connections.ts b/src/services/api/routes/v1/connections.ts deleted file mode 100644 index 2ddf36d..0000000 --- a/src/services/api/routes/v1/connections.ts +++ /dev/null @@ -1,105 +0,0 @@ -import express from 'express'; -import { addPNIDConnection, removePNIDConnection } from '@/database'; - -const router = express.Router(); - -const VALID_CONNECTION_TYPES = [ - 'discord' -]; - -/** - * [POST] - * Implementation of for: https://api.pretendo.cc/v1/connections/add/TYPE - * Description: Adds an account connection to the users PNID - */ -router.post('/add/:type', async (request: express.Request, response: express.Response): Promise => { - const data = request.body?.data; - const pnid = request.pnid; - const type = request.params.type; - - if (!pnid) { - response.status(400).json({ - app: 'api', - status: 400, - error: 'Invalid or missing access token' - }); - - return; - } - - if (!data) { - response.status(400).json({ - app: 'api', - status: 400, - error: 'Invalid or missing connection data' - }); - - return; - } - - if (!VALID_CONNECTION_TYPES.includes(type)) { - response.status(400).json({ - app: 'api', - status: 400, - error: 'Invalid or missing connection type' - }); - - return; - } - - let result = await addPNIDConnection(pnid, data, type); - - if (!result) { - result = { - app: 'api', - status: 500, - error: 'Unknown server error' - }; - } - - response.status(result.status || 500).json(result); -}); - -/** - * [DELETE] - * Implementation of for: https://api.pretendo.cc/v1/connections/remove/TYPE - * Description: Removes an account connection from the users PNID - */ -router.delete('/remove/:type', async (request: express.Request, response: express.Response): Promise => { - const pnid = request.pnid; - const type = request.params.type; - - if (!pnid) { - response.status(400).json({ - app: 'api', - status: 400, - error: 'Invalid or missing access token' - }); - - return; - } - - if (!VALID_CONNECTION_TYPES.includes(type)) { - response.status(400).json({ - app: 'api', - status: 400, - error: 'Invalid or missing connection type' - }); - - return; - } - - let result = await removePNIDConnection(pnid, type); - - if (!result) { - result = { - app: 'api', - status: 500, - error: 'Unknown server error' - }; - } - - response.status(result.status).json(result); -}); - -export default router; diff --git a/src/services/api/routes/v1/login.ts b/src/services/api/routes/v1/login.ts index 1fcf826..5ea2b21 100644 --- a/src/services/api/routes/v1/login.ts +++ b/src/services/api/routes/v1/login.ts @@ -1,11 +1,13 @@ +import crypto from 'node:crypto'; import express from 'express'; import bcrypt from 'bcrypt'; import { getPNIDByUsername, getPNIDByAPIRefreshToken } from '@/database'; -import { nintendoPasswordHash, generateToken } from '@/util'; +import { nintendoPasswordHash } from '@/util'; +import { OAuthToken } from '@/models/oauth-token'; import { SystemType } from '@/types/common/system-types'; import { TokenType } from '@/types/common/token-types'; -import { config } from '@/config-manager'; import { LOG_ERROR } from '@/logger'; +import { loginRatelimit } from '@/middleware/ratelimit'; import type { HydratedPNIDDocument } from '@/types/mongoose/pnid'; const router = express.Router(); @@ -16,7 +18,7 @@ const router = express.Router(); * Description: Generates an access token for an API user * TODO: Replace this with a more robust OAuth2 implementation */ -router.post('/', async (request: express.Request, response: express.Response): Promise => { +router.post('/', loginRatelimit, async (request: express.Request, response: express.Response): Promise => { const grantType = request.body?.grant_type; const username = request.body?.username; const password = request.body?.password; @@ -102,7 +104,7 @@ router.post('/', async (request: express.Request, response: express.Response): P } } - if (pnid.deleted) { + if (pnid.deleted || pnid.marked_for_deletion) { response.status(400).json({ app: 'api', status: 400, @@ -112,30 +114,37 @@ router.post('/', async (request: express.Request, response: express.Response): P return; } - const accessTokenOptions = { - system_type: SystemType.API, - token_type: TokenType.OAuthAccess, - pid: pnid.pid, - access_level: pnid.access_level, - title_id: BigInt(0), - expire_time: BigInt(Date.now() + (3600 * 1000)) - }; - - const refreshTokenOptions = { - system_type: SystemType.API, - token_type: TokenType.OAuthRefresh, - pid: pnid.pid, - access_level: pnid.access_level, - title_id: BigInt(0), - expire_time: BigInt(Date.now() + 12 * 3600 * 1000) - }; - try { - const accessTokenBuffer = await generateToken(config.aes_key, accessTokenOptions); - const refreshTokenBuffer = await generateToken(config.aes_key, refreshTokenOptions); + const accessToken = crypto.randomBytes(16).toString('hex'); + const newRefreshToken = crypto.randomBytes(20).toString('hex'); - const accessToken = accessTokenBuffer ? accessTokenBuffer.toString('hex') : ''; - const newRefreshToken = refreshTokenBuffer ? refreshTokenBuffer.toString('hex') : ''; + await OAuthToken.create({ + token: crypto.createHash('sha256').update(accessToken).digest('hex'), + client_id: 'a2efa818a34fa16b8afbc8a74eba3eda', // TODO - This is the Wii U config, change this? + client_secret: 'c91cdb5658bd4954ade78533a339cf9a', // TODO - This is the Wii U config, change this? + pid: pnid.pid, + info: { + system_type: SystemType.API, + token_type: TokenType.OAuthAccess, + title_id: BigInt(0), + issued: new Date(), + expires: new Date(Date.now() + (3600 * 1000)) + } + }); + + await OAuthToken.create({ + token: crypto.createHash('sha256').update(newRefreshToken).digest('hex'), + client_id: 'a2efa818a34fa16b8afbc8a74eba3eda', // TODO - This is the Wii U config, change this? + client_secret: 'c91cdb5658bd4954ade78533a339cf9a', // TODO - This is the Wii U config, change this? + pid: pnid.pid, + info: { + system_type: SystemType.API, + token_type: TokenType.OAuthRefresh, + title_id: BigInt(0), + issued: new Date(), + expires: new Date(Date.now() + 12 * 3600 * 1000) + } + }); // TODO - Handle null tokens diff --git a/src/services/api/routes/v1/register.ts b/src/services/api/routes/v1/register.ts index fcc3ce3..0707d1f 100644 --- a/src/services/api/routes/v1/register.ts +++ b/src/services/api/routes/v1/register.ts @@ -6,14 +6,16 @@ import moment from 'moment'; import hcaptcha from 'hcaptcha'; import Mii from 'mii-js'; import { doesPNIDExist, connection as databaseConnection } from '@/database'; -import { isValidBirthday, getAgeFromDate, nintendoPasswordHash, sendConfirmationEmail, generateToken } from '@/util'; +import { isValidBirthday, getAgeFromDate, nintendoPasswordHash, sendConfirmationEmail } from '@/util'; import IP2LocationManager from '@/ip2location'; import { SystemType } from '@/types/common/system-types'; import { TokenType } from '@/types/common/token-types'; import { LOG_ERROR } from '@/logger'; import { PNID } from '@/models/pnid'; +import { OAuthToken } from '@/models/oauth-token'; import { NEXAccount } from '@/models/nex-account'; import { config, disabledFeatures } from '@/config-manager'; +import { webRegisterRatelimit } from '@/middleware/ratelimit'; import type { HydratedNEXAccountDocument } from '@/types/mongoose/nex-account'; import type { HydratedPNIDDocument } from '@/types/mongoose/pnid'; @@ -37,7 +39,7 @@ const DEFAULT_MII_DATA = Buffer.from('AwAAQOlVognnx0GC2/uogAOzuI0n2QAAAEBEAGUAZg * Implementation of: https://api.pretendo.cc/v1/register * Description: Creates a new user PNID */ -router.post('/', async (request: express.Request, response: express.Response): Promise => { +router.post('/', webRegisterRatelimit, async (request: express.Request, response: express.Response): Promise => { const clientIP = request.body.ip?.trim(); // * This has to be forwarded since this request comes from the websites server const birthday = request.body.birthday?.trim(); const email = request.body.email?.trim(); @@ -118,6 +120,22 @@ router.post('/', async (request: express.Request, response: express.Response): P } } + if (age < 13) { + // * Wii U firmware 5.5.6 changed NNID setup to block setup of new accounts if the users age is + // * under 13, telling parents that they MUST call Nintendo to create the account, and we trusted + // * that users would be on these firmwares. Lower firmwares won't have this though, and will use + // * the old "COPPA approval" system + // * + // * Just block it all the time though, we don't want to deal with this headache + response.status(400).json({ + app: 'api', + status: 400, + error: 'Must be 13 or older to use these services.' + }); + + return; + } + if (!email || email === '') { response.status(400).json({ app: 'api', @@ -419,32 +437,37 @@ router.post('/', async (request: express.Request, response: express.Response): P await sendConfirmationEmail(pnid); - const accessTokenOptions = { - system_type: SystemType.API, - token_type: TokenType.OAuthAccess, - pid: pnid.pid, - access_level: pnid.access_level, - title_id: BigInt(0), - expire_time: BigInt(Date.now() + (3600 * 1000)) - }; - - const refreshTokenOptions = { - system_type: SystemType.API, - token_type: TokenType.OAuthRefresh, - pid: pnid.pid, - access_level: pnid.access_level, - title_id: BigInt(0), - expire_time: BigInt(Date.now() + 12 * 3600 * 1000) - }; - try { - const accessTokenBuffer = await generateToken(config.aes_key, accessTokenOptions); - const refreshTokenBuffer = await generateToken(config.aes_key, refreshTokenOptions); + const accessToken = crypto.randomBytes(16).toString('hex'); + const refreshToken = crypto.randomBytes(20).toString('hex'); - const accessToken = accessTokenBuffer ? accessTokenBuffer.toString('hex') : ''; - const refreshToken = refreshTokenBuffer ? refreshTokenBuffer.toString('hex') : ''; + await OAuthToken.create({ + token: crypto.createHash('sha256').update(accessToken).digest('hex'), + client_id: 'a2efa818a34fa16b8afbc8a74eba3eda', // TODO - This is the Wii U config, change this? + client_secret: 'c91cdb5658bd4954ade78533a339cf9a', // TODO - This is the Wii U config, change this? + pid: pnid.pid, + info: { + system_type: SystemType.API, + token_type: TokenType.OAuthAccess, + title_id: BigInt(0), + issued: new Date(), + expires: new Date(Date.now() + (3600 * 1000)) + } + }); - // TODO - Handle null tokens + await OAuthToken.create({ + token: crypto.createHash('sha256').update(refreshToken).digest('hex'), + client_id: 'a2efa818a34fa16b8afbc8a74eba3eda', // TODO - This is the Wii U config, change this? + client_secret: 'c91cdb5658bd4954ade78533a339cf9a', // TODO - This is the Wii U config, change this? + pid: pnid.pid, + info: { + system_type: SystemType.API, + token_type: TokenType.OAuthRefresh, + title_id: BigInt(0), + issued: new Date(), + expires: new Date(Date.now() + 12 * 3600 * 1000) + } + }); response.json({ access_token: accessToken, diff --git a/src/services/api/routes/v1/resetPassword.ts b/src/services/api/routes/v1/resetPassword.ts index b7c5dcc..1b1f1ce 100644 --- a/src/services/api/routes/v1/resetPassword.ts +++ b/src/services/api/routes/v1/resetPassword.ts @@ -1,8 +1,13 @@ +import crypto from 'node:crypto'; import express from 'express'; import bcrypt from 'bcrypt'; -import { PNID } from '@/models/pnid'; -import { decryptToken, unpackToken, nintendoPasswordHash } from '@/util'; -import type { Token } from '@/types/common/token'; +import { PasswordResetToken } from '@/models/password-reset-token'; +import { nintendoPasswordHash } from '@/util'; +import { SystemType } from '@/types/common/system-types'; +import { TokenType } from '@/types/common/token-types'; +import { getPNIDByPID } from '@/database'; +import { passwordResetRatelimit } from '@/middleware/ratelimit'; +import type { HydratedPNIDDocument } from '@/types/mongoose/pnid'; const router = express.Router(); @@ -12,7 +17,7 @@ const PASSWORD_WORD_OR_PUNCTUATION_REGEX = /(?=.*[a-zA-Z])(?=.*[_\-.]).*/; const PASSWORD_NUMBER_OR_PUNCTUATION_REGEX = /(?=.*\d)(?=.*[_\-.]).*/; const PASSWORD_REPEATED_CHARACTER_REGEX = /(.)\1\1/; -router.post('/', async (request: express.Request, response: express.Response): Promise => { +router.post('/', passwordResetRatelimit, async (request: express.Request, response: express.Response): Promise => { const password = request.body.password?.trim(); const passwordConfirm = request.body.password_confirm?.trim(); const token = request.body.token?.trim(); @@ -27,10 +32,53 @@ router.post('/', async (request: express.Request, response: express.Response): P return; } - let unpackedToken: Token; + let pnid: HydratedPNIDDocument | null = null; try { - const decryptedToken = await decryptToken(Buffer.from(token, 'hex')); - unpackedToken = unpackToken(decryptedToken); + const passwordResetToken = await PasswordResetToken.findOne({ + token: crypto.createHash('sha256').update(token).digest('hex') + }); + + if (!passwordResetToken) { + response.status(400).json({ + app: 'api', + status: 400, + error: 'Invalid token' + }); + + return; + } + + if (passwordResetToken.info.system_type !== SystemType.PasswordReset) { + response.status(400).json({ + app: 'api', + status: 400, + error: 'Invalid token' + }); + + return; + } + + if (passwordResetToken.info.token_type !== TokenType.PasswordReset) { + response.status(400).json({ + app: 'api', + status: 400, + error: 'Invalid token' + }); + + return; + } + + if (passwordResetToken.info.expires < new Date()) { + response.status(400).json({ + app: 'api', + status: 400, + error: 'Token expired' + }); + + return; + } + + pnid = await getPNIDByPID(passwordResetToken.pid); } catch { response.status(400).json({ app: 'api', @@ -41,18 +89,6 @@ router.post('/', async (request: express.Request, response: express.Response): P return; } - if (unpackedToken.expire_time < Date.now()) { - response.status(400).json({ - app: 'api', - status: 400, - error: 'Token expired' - }); - - return; - } - - const pnid = await PNID.findOne({ pid: unpackedToken.pid }); - if (!pnid) { response.status(400).json({ app: 'api', @@ -138,6 +174,7 @@ router.post('/', async (request: express.Request, response: express.Response): P pnid.password = passwordHash; + await pnid.removeAllTokens(); await pnid.save(); response.json({ diff --git a/src/services/grpc/account/v1/exchange-token-for-user-data.ts b/src/services/grpc/account/v1/exchange-token-for-user-data.ts index e19897a..f52cfbf 100644 --- a/src/services/grpc/account/v1/exchange-token-for-user-data.ts +++ b/src/services/grpc/account/v1/exchange-token-for-user-data.ts @@ -17,7 +17,7 @@ export async function exchangeTokenForUserData(request: ExchangeTokenForUserData } return { - deleted: pnid.deleted, + deleted: pnid.deleted || pnid.marked_for_deletion, pid: pnid.pid, username: pnid.username, accessLevel: pnid.access_level, diff --git a/src/services/grpc/account/v1/get-user-data.ts b/src/services/grpc/account/v1/get-user-data.ts index bce0c65..aeab9f5 100644 --- a/src/services/grpc/account/v1/get-user-data.ts +++ b/src/services/grpc/account/v1/get-user-data.ts @@ -15,7 +15,7 @@ export async function getUserData(request: GetUserDataRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/create-ban-comment.ts b/src/services/grpc/account/v2/create-ban-comment.ts new file mode 100644 index 0000000..aee6d6d --- /dev/null +++ b/src/services/grpc/account/v2/create-ban-comment.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { CreateBanCommentRequest, CreateBanCommentResponse } from '@pretendonetwork/grpc/account/v2/create_ban_comment_rpc'; + +export async function createBanComment(_request: CreateBanCommentRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/create-server.ts b/src/services/grpc/account/v2/create-server.ts new file mode 100644 index 0000000..f681893 --- /dev/null +++ b/src/services/grpc/account/v2/create-server.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { CreateServerRequest, CreateServerResponse } from '@pretendonetwork/grpc/account/v2/create_server_rpc'; + +export async function createServer(_request: CreateServerRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/delete-account.ts b/src/services/grpc/account/v2/delete-account.ts index 869f405..e4c80cc 100644 --- a/src/services/grpc/account/v2/delete-account.ts +++ b/src/services/grpc/account/v2/delete-account.ts @@ -1,7 +1,7 @@ import { Status, ServerError } from 'nice-grpc'; import { getPNIDByPID } from '@/database'; import { sendPNIDDeletedEmail } from '@/util'; -import { LOG_ERROR } from '@/logger'; +import { LOG_ERROR, LOG_INFO } from '@/logger'; import type { DeleteAccountRequest, DeleteAccountResponse } from '@pretendonetwork/grpc/account/v2/delete_account_rpc'; export async function deleteAccount(request: DeleteAccountRequest): Promise { @@ -15,17 +15,27 @@ export async function deleteAccount(request: DeleteAccountRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/delete-server.ts b/src/services/grpc/account/v2/delete-server.ts new file mode 100644 index 0000000..cb0203e --- /dev/null +++ b/src/services/grpc/account/v2/delete-server.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { DeleteServerRequest, DeleteServerResponse } from '@pretendonetwork/grpc/account/v2/delete_server_rpc'; + +export async function deleteServer(_request: DeleteServerRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/exchange-independent-service-token-for-user-data.ts b/src/services/grpc/account/v2/exchange-independent-service-token-for-user-data.ts new file mode 100644 index 0000000..28ab51b --- /dev/null +++ b/src/services/grpc/account/v2/exchange-independent-service-token-for-user-data.ts @@ -0,0 +1,153 @@ +import crypto from 'node:crypto'; +import { Status, ServerError } from 'nice-grpc'; +import { IndependentServiceToken } from '@/models/independent-service-token'; +import { Device } from '@/models/device'; +import { NEXAccount } from '@/models/nex-account'; +import { getPNIDByPID } from '@/database'; +import { PNID_PERMISSION_FLAGS } from '@/types/common/permission-flags'; +import { config } from '@/config-manager'; +import type { ExchangeIndependentServiceTokenForUserDataRequest, ExchangeIndependentServiceTokenForUserDataResponse } from '@pretendonetwork/grpc/account/v2/exchange_independent_service_token_for_user_data_rpc'; +import type { HydratedPNIDDocument } from '@/types/mongoose/pnid'; +import type { HydratedNEXAccountDocument } from '@/types/mongoose/nex-account'; +import type { HydratedIndependentServiceTokenDocument } from '@/models/independent-service-token'; + +export async function exchangeIndependentServiceTokenForUserData(request: ExchangeIndependentServiceTokenForUserDataRequest): Promise { + let pnid: HydratedPNIDDocument | null = null; + let nexAccount: HydratedNEXAccountDocument | null = null; + let serviceToken: HydratedIndependentServiceTokenDocument | null = null; + try { + serviceToken = await IndependentServiceToken.findOne({ + token: crypto.createHash('sha256').update(request.token).digest('hex') + }); + + if (!serviceToken) { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); + } + + // TODO - Add checks for the client IDs and matching system/token types here + + if (serviceToken.info.expires < new Date()) { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); + } + + pnid = await getPNIDByPID(serviceToken.pid); + nexAccount = await NEXAccount.findOne({ pid: serviceToken.pid }); + } catch { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); + } + + if (!nexAccount) { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token. No user found'); + } + + // TODO - Change this. This duplication sucks, but I wanna push this out the door + if (pnid) { + const devices = (await Device.find({ + linked_pids: pnid.pid + })).map((device) => { + return { + model: device.get('model'), // * ".model" gives the Mongoose model + serial: device.serial, + linkedPids: device.linked_pids, + accessLevel: device.access_level, + serverAccessLevel: device.server_access_level, + deviceId: device.device_id + }; + }); + + return { + pnid: { + deleted: pnid.deleted, + pid: pnid.pid, + username: pnid.username, + accessLevel: pnid.access_level, + serverAccessLevel: pnid.server_access_level, + mii: { + name: pnid.mii.name, + data: pnid.mii.data, + url: `${config.cdn.base_url}/mii/${pnid.pid}/standard.tga` + }, + creationDate: pnid.creation_date, + birthdate: pnid.birthdate, + gender: pnid.gender, + country: pnid.country, + language: pnid.language, + emailAddress: pnid.email.address, + tierName: pnid.connections.stripe.tier_name, + permissions: { + bannedAllPermanently: pnid.hasPermission(PNID_PERMISSION_FLAGS.BANNED_ALL_PERMANENTLY), + bannedAllTemporarily: pnid.hasPermission(PNID_PERMISSION_FLAGS.BANNED_ALL_TEMPORARILY), + betaAccess: pnid.hasPermission(PNID_PERMISSION_FLAGS.BETA_ACCESS), + accessAdminPanel: pnid.hasPermission(PNID_PERMISSION_FLAGS.ACCESS_ADMIN_PANEL), + createServerConfigs: pnid.hasPermission(PNID_PERMISSION_FLAGS.CREATE_SERVER_CONFIGS), + modifyServerConfigs: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_SERVER_CONFIGS), + deployServer: pnid.hasPermission(PNID_PERMISSION_FLAGS.DEPLOY_SERVER), + modifyPnids: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_PNIDS), + modifyNexAccounts: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_NEX_ACCOUNTS), + modifyConsoles: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_CONSOLES), + banPnids: pnid.hasPermission(PNID_PERMISSION_FLAGS.BAN_PNIDS), + banNexAccounts: pnid.hasPermission(PNID_PERMISSION_FLAGS.BAN_NEX_ACCOUNTS), + banConsoles: pnid.hasPermission(PNID_PERMISSION_FLAGS.BAN_CONSOLES), + moderateMiiverse: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODERATE_MIIVERSE), + createApiKeys: pnid.hasPermission(PNID_PERMISSION_FLAGS.CREATE_API_KEYS), + createBossTasks: pnid.hasPermission(PNID_PERMISSION_FLAGS.CREATE_BOSS_TASKS), + updateBossTasks: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPDATE_BOSS_TASKS), + deleteBossTasks: pnid.hasPermission(PNID_PERMISSION_FLAGS.DELETE_BOSS_TASKS), + uploadBossFiles: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPLOAD_BOSS_FILES), + updateBossFiles: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPDATE_BOSS_FILES), + deleteBossFiles: pnid.hasPermission(PNID_PERMISSION_FLAGS.DELETE_BOSS_FILES), + updatePnidPermissions: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPDATE_PNID_PERMISSIONS) + }, + linkedDevices: devices + }, + nexAccount: { + pid: nexAccount.pid, + owningPid: nexAccount.owning_pid, + accessLevel: nexAccount.access_level, + serverAccessLevel: nexAccount.server_access_level, + friendCode: nexAccount.friend_code, + deviceType: nexAccount.device_type + }, + tokenInfo: { + systemType: serviceToken.info.system_type as any, // TODO - Stop the any usage + tokenType: serviceToken.info.token_type as any, // TODO - Stop the any usage + pid: BigInt(pnid.pid), + accessLevel: pnid.access_level, + titleId: serviceToken.info.title_id, + issueTime: serviceToken.info.issued, + expireTime: serviceToken.info.expires + }, + basicUserInfo: { + // TODO - ban: {} + accessBetaServers: pnid.access_level === 1 || pnid.access_level === 2 || pnid.access_level === 3, // TODO - Remove with a better permission check later + accessDeveloperServers: pnid.access_level === 3 // TODO - Remove with a better permission check later + } + }; + } else { + return { + pnid: undefined, // * Throws an error if this is not explictly set? + nexAccount: { + pid: nexAccount.pid, + owningPid: nexAccount.owning_pid, + accessLevel: nexAccount.access_level, + serverAccessLevel: nexAccount.server_access_level, + friendCode: nexAccount.friend_code, + deviceType: nexAccount.device_type + }, + tokenInfo: { + systemType: serviceToken.info.system_type as any, // TODO - Stop the any usage + tokenType: serviceToken.info.token_type as any, // TODO - Stop the any usage + pid: BigInt(nexAccount.pid), + accessLevel: nexAccount.access_level, + titleId: serviceToken.info.title_id, + issueTime: serviceToken.info.issued, + expireTime: serviceToken.info.expires + }, + basicUserInfo: { + // TODO - ban: {} + accessBetaServers: nexAccount.access_level === 1 || nexAccount.access_level === 2 || nexAccount.access_level === 3, // TODO - Remove with a better permission check later + accessDeveloperServers: nexAccount.access_level === 3 // TODO - Remove with a better permission check later + } + }; + } +} diff --git a/src/services/grpc/account/v2/exchange-nex-token-for-user-data.ts b/src/services/grpc/account/v2/exchange-nex-token-for-user-data.ts new file mode 100644 index 0000000..e39df29 --- /dev/null +++ b/src/services/grpc/account/v2/exchange-nex-token-for-user-data.ts @@ -0,0 +1,90 @@ +import crypto from 'node:crypto'; +import { Status, ServerError } from 'nice-grpc'; +import { NEXToken } from '@/models/nex-token'; +import { NEXAccount } from '@/models/nex-account'; +import { getPNIDByPID } from '@/database'; +import type { ExchangeNEXTokenForUserDataRequest, ExchangeNEXTokenForUserDataResponse } from '@pretendonetwork/grpc/account/v2/exchange_nex_token_for_user_data_rpc'; +import type { HydratedNEXAccountDocument } from '@/types/mongoose/nex-account'; +import type { HydratedNEXTokenDocument } from '@/models/nex-token'; + +export async function exchangeNEXTokenForUserData(request: ExchangeNEXTokenForUserDataRequest): Promise { + let nexAccount: HydratedNEXAccountDocument | null = null; + let nexToken: HydratedNEXTokenDocument | null = null; + try { + nexToken = await NEXToken.findOne({ + token: crypto.createHash('sha256').update(request.token).digest('hex') + }); + + if (!nexToken) { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); + } + + // TODO - Add checks for the game server ID and matching system/token types here + + if (nexToken.info.expires < new Date()) { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); + } + + nexAccount = await NEXAccount.findOne({ pid: nexToken.pid }); + } catch { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); + } + + if (!nexAccount) { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token. No user found'); + } + + const pnid = await getPNIDByPID(nexAccount.owning_pid || nexAccount.pid); + + if (pnid) { + return { + nexAccount: { + pid: nexAccount.pid, + owningPid: nexAccount.owning_pid, + accessLevel: nexAccount.access_level, + serverAccessLevel: nexAccount.server_access_level, + friendCode: nexAccount.friend_code, + deviceType: nexAccount.device_type + }, + tokenInfo: { + systemType: nexToken.info.system_type as any, // TODO - Stop the any usage + tokenType: nexToken.info.token_type as any, // TODO - Stop the any usage + pid: BigInt(nexAccount.pid), + accessLevel: nexAccount.access_level, + titleId: nexToken.info.title_id, + issueTime: nexToken.info.issued, + expireTime: nexToken.info.expires + }, + basicUserInfo: { + // TODO - ban: {} + accessBetaServers: pnid.access_level === 1 || pnid.access_level === 2 || pnid.access_level === 3, // TODO - Remove with a better permission check later + accessDeveloperServers: pnid.access_level === 3 // TODO - Remove with a better permission check later + } + }; + } else { + return { + nexAccount: { + pid: nexAccount.pid, + owningPid: nexAccount.owning_pid, + accessLevel: nexAccount.access_level, + serverAccessLevel: nexAccount.server_access_level, + friendCode: nexAccount.friend_code, + deviceType: nexAccount.device_type + }, + tokenInfo: { + systemType: nexToken.info.system_type as any, // TODO - Stop the any usage + tokenType: nexToken.info.token_type as any, // TODO - Stop the any usage + pid: BigInt(nexAccount.pid), + accessLevel: nexAccount.access_level, + titleId: nexToken.info.title_id, + issueTime: nexToken.info.issued, + expireTime: nexToken.info.expires + }, + basicUserInfo: { + // TODO - ban: {} + accessBetaServers: nexAccount.access_level === 1 || nexAccount.access_level === 2 || nexAccount.access_level === 3, // TODO - Remove with a better permission check later + accessDeveloperServers: nexAccount.access_level === 3 // TODO - Remove with a better permission check later + } + }; + } +} diff --git a/src/services/grpc/account/v2/exchange-oauth-token-for-user-data.ts b/src/services/grpc/account/v2/exchange-oauth-token-for-user-data.ts new file mode 100644 index 0000000..3c6de65 --- /dev/null +++ b/src/services/grpc/account/v2/exchange-oauth-token-for-user-data.ts @@ -0,0 +1,124 @@ +import crypto from 'node:crypto'; +import { Status, ServerError } from 'nice-grpc'; +import { OAuthToken } from '@/models/oauth-token'; +import { Device } from '@/models/device'; +import { NEXAccount } from '@/models/nex-account'; +import { getPNIDByPID } from '@/database'; +import { PNID_PERMISSION_FLAGS } from '@/types/common/permission-flags'; +import { config } from '@/config-manager'; +import type { ExchangeOAuthTokenForUserDataRequest, ExchangeOAuthTokenForUserDataResponse } from '@pretendonetwork/grpc/account/v2/exchange_oauth_token_for_user_data_rpc'; +import type { HydratedPNIDDocument } from '@/types/mongoose/pnid'; +import type { HydratedNEXAccountDocument } from '@/types/mongoose/nex-account'; +import type { HydratedOAuthTokenDocument } from '@/models/oauth-token'; + +export async function exchangeOAuthTokenForUserData(request: ExchangeOAuthTokenForUserDataRequest): Promise { + let pnid: HydratedPNIDDocument | null = null; + let nexAccount: HydratedNEXAccountDocument | null = null; + let oAuthToken: HydratedOAuthTokenDocument | null = null; + try { + oAuthToken = await OAuthToken.findOne({ + token: crypto.createHash('sha256').update(request.token).digest('hex') + }); + + if (!oAuthToken) { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); + } + + // TODO - Add checks for the client ID/title ID and matching system/token types here + + if (oAuthToken.info.expires < new Date()) { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); + } + + pnid = await getPNIDByPID(oAuthToken.pid); + nexAccount = await NEXAccount.findOne({ pid: oAuthToken.pid }); + } catch { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); + } + + if (!nexAccount || !pnid) { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token. No user found'); + } + + const devices = (await Device.find({ + linked_pids: pnid.pid + })).map((device) => { + return { + model: device.get('model'), // * ".model" gives the Mongoose model + serial: device.serial, + linkedPids: device.linked_pids, + accessLevel: device.access_level, + serverAccessLevel: device.server_access_level, + deviceId: device.device_id + }; + }); + + return { + pnid: { + deleted: pnid.deleted, + pid: pnid.pid, + username: pnid.username, + accessLevel: pnid.access_level, + serverAccessLevel: pnid.server_access_level, + mii: { + name: pnid.mii.name, + data: pnid.mii.data, + url: `${config.cdn.base_url}/mii/${pnid.pid}/standard.tga` + }, + creationDate: pnid.creation_date, + birthdate: pnid.birthdate, + gender: pnid.gender, + country: pnid.country, + language: pnid.language, + emailAddress: pnid.email.address, + tierName: pnid.connections.stripe.tier_name, + permissions: { + bannedAllPermanently: pnid.hasPermission(PNID_PERMISSION_FLAGS.BANNED_ALL_PERMANENTLY), + bannedAllTemporarily: pnid.hasPermission(PNID_PERMISSION_FLAGS.BANNED_ALL_TEMPORARILY), + betaAccess: pnid.hasPermission(PNID_PERMISSION_FLAGS.BETA_ACCESS), + accessAdminPanel: pnid.hasPermission(PNID_PERMISSION_FLAGS.ACCESS_ADMIN_PANEL), + createServerConfigs: pnid.hasPermission(PNID_PERMISSION_FLAGS.CREATE_SERVER_CONFIGS), + modifyServerConfigs: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_SERVER_CONFIGS), + deployServer: pnid.hasPermission(PNID_PERMISSION_FLAGS.DEPLOY_SERVER), + modifyPnids: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_PNIDS), + modifyNexAccounts: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_NEX_ACCOUNTS), + modifyConsoles: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_CONSOLES), + banPnids: pnid.hasPermission(PNID_PERMISSION_FLAGS.BAN_PNIDS), + banNexAccounts: pnid.hasPermission(PNID_PERMISSION_FLAGS.BAN_NEX_ACCOUNTS), + banConsoles: pnid.hasPermission(PNID_PERMISSION_FLAGS.BAN_CONSOLES), + moderateMiiverse: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODERATE_MIIVERSE), + createApiKeys: pnid.hasPermission(PNID_PERMISSION_FLAGS.CREATE_API_KEYS), + createBossTasks: pnid.hasPermission(PNID_PERMISSION_FLAGS.CREATE_BOSS_TASKS), + updateBossTasks: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPDATE_BOSS_TASKS), + deleteBossTasks: pnid.hasPermission(PNID_PERMISSION_FLAGS.DELETE_BOSS_TASKS), + uploadBossFiles: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPLOAD_BOSS_FILES), + updateBossFiles: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPDATE_BOSS_FILES), + deleteBossFiles: pnid.hasPermission(PNID_PERMISSION_FLAGS.DELETE_BOSS_FILES), + updatePnidPermissions: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPDATE_PNID_PERMISSIONS) + }, + linkedDevices: devices + }, + nexAccount: { + pid: nexAccount.pid, + owningPid: nexAccount.owning_pid, + accessLevel: nexAccount.access_level, + serverAccessLevel: nexAccount.server_access_level, + friendCode: nexAccount.friend_code, + deviceType: nexAccount.device_type + }, + tokenInfo: { + systemType: oAuthToken.info.system_type as any, // TODO - Stop the any usage + tokenType: oAuthToken.info.token_type as any, // TODO - Stop the any usage + pid: BigInt(pnid.pid), + accessLevel: pnid.access_level, + titleId: oAuthToken.info.title_id, + issueTime: oAuthToken.info.issued, + expireTime: oAuthToken.info.expires + }, + basicUserInfo: { + // TODO - ban: {} + accessBetaServers: pnid.access_level === 1 || pnid.access_level === 2 || pnid.access_level === 3, // TODO - Remove with a better permission check later + accessDeveloperServers: pnid.access_level === 3 // TODO - Remove with a better permission check later + } + }; +} diff --git a/src/services/grpc/account/v2/exchange-password-reset-token-for-user-data.ts b/src/services/grpc/account/v2/exchange-password-reset-token-for-user-data.ts new file mode 100644 index 0000000..62f7dd0 --- /dev/null +++ b/src/services/grpc/account/v2/exchange-password-reset-token-for-user-data.ts @@ -0,0 +1,120 @@ +import crypto from 'node:crypto'; +import { Status, ServerError } from 'nice-grpc'; +import { PasswordResetToken } from '@/models/password-reset-token'; +import { Device } from '@/models/device'; +import { SystemType } from '@/types/common/system-types'; +import { TokenType } from '@/types/common/token-types'; +import { getPNIDByPID } from '@/database'; +import { PNID_PERMISSION_FLAGS } from '@/types/common/permission-flags'; +import { config } from '@/config-manager'; +import type { ExchangePasswordResetTokenForUserDataRequest, ExchangePasswordResetTokenForUserDataResponse } from '@pretendonetwork/grpc/account/v2/exchange_password_reset_token_for_user_data_rpc'; +import type { HydratedPNIDDocument } from '@/types/mongoose/pnid'; +import type { HydratedPasswordResetTokenDocument } from '@/models/password-reset-token'; + +export async function exchangePasswordResetTokenForUserData(request: ExchangePasswordResetTokenForUserDataRequest): Promise { + let pnid: HydratedPNIDDocument | null = null; + let passwordResetToken: HydratedPasswordResetTokenDocument | null = null; + try { + passwordResetToken = await PasswordResetToken.findOne({ + token: crypto.createHash('sha256').update(request.token).digest('hex') + }); + + if (!passwordResetToken) { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); + } + + if (passwordResetToken.info.system_type !== SystemType.PasswordReset) { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); + } + + if (passwordResetToken.info.token_type !== TokenType.PasswordReset) { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); + } + + if (passwordResetToken.info.expires < new Date()) { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); + } + + pnid = await getPNIDByPID(passwordResetToken.pid); + } catch { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); + } + + if (!pnid) { + throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token. No user found'); + } + + const devices = (await Device.find({ + linked_pids: pnid.pid + })).map((device) => { + return { + model: device.get('model'), // * ".model" gives the Mongoose model + serial: device.serial, + linkedPids: device.linked_pids, + accessLevel: device.access_level, + serverAccessLevel: device.server_access_level, + deviceId: device.device_id + }; + }); + + return { + pnid: { + deleted: pnid.deleted, + pid: pnid.pid, + username: pnid.username, + accessLevel: pnid.access_level, + serverAccessLevel: pnid.server_access_level, + mii: { + name: pnid.mii.name, + data: pnid.mii.data, + url: `${config.cdn.base_url}/mii/${pnid.pid}/standard.tga` + }, + creationDate: pnid.creation_date, + birthdate: pnid.birthdate, + gender: pnid.gender, + country: pnid.country, + language: pnid.language, + emailAddress: pnid.email.address, + tierName: pnid.connections.stripe.tier_name, + permissions: { + bannedAllPermanently: pnid.hasPermission(PNID_PERMISSION_FLAGS.BANNED_ALL_PERMANENTLY), + bannedAllTemporarily: pnid.hasPermission(PNID_PERMISSION_FLAGS.BANNED_ALL_TEMPORARILY), + betaAccess: pnid.hasPermission(PNID_PERMISSION_FLAGS.BETA_ACCESS), + accessAdminPanel: pnid.hasPermission(PNID_PERMISSION_FLAGS.ACCESS_ADMIN_PANEL), + createServerConfigs: pnid.hasPermission(PNID_PERMISSION_FLAGS.CREATE_SERVER_CONFIGS), + modifyServerConfigs: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_SERVER_CONFIGS), + deployServer: pnid.hasPermission(PNID_PERMISSION_FLAGS.DEPLOY_SERVER), + modifyPnids: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_PNIDS), + modifyNexAccounts: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_NEX_ACCOUNTS), + modifyConsoles: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_CONSOLES), + banPnids: pnid.hasPermission(PNID_PERMISSION_FLAGS.BAN_PNIDS), + banNexAccounts: pnid.hasPermission(PNID_PERMISSION_FLAGS.BAN_NEX_ACCOUNTS), + banConsoles: pnid.hasPermission(PNID_PERMISSION_FLAGS.BAN_CONSOLES), + moderateMiiverse: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODERATE_MIIVERSE), + createApiKeys: pnid.hasPermission(PNID_PERMISSION_FLAGS.CREATE_API_KEYS), + createBossTasks: pnid.hasPermission(PNID_PERMISSION_FLAGS.CREATE_BOSS_TASKS), + updateBossTasks: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPDATE_BOSS_TASKS), + deleteBossTasks: pnid.hasPermission(PNID_PERMISSION_FLAGS.DELETE_BOSS_TASKS), + uploadBossFiles: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPLOAD_BOSS_FILES), + updateBossFiles: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPDATE_BOSS_FILES), + deleteBossFiles: pnid.hasPermission(PNID_PERMISSION_FLAGS.DELETE_BOSS_FILES), + updatePnidPermissions: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPDATE_PNID_PERMISSIONS) + }, + linkedDevices: devices + }, + tokenInfo: { + systemType: passwordResetToken.info.system_type as any, // TODO - Stop the any usage + tokenType: passwordResetToken.info.token_type as any, // TODO - Stop the any usage + pid: BigInt(pnid.pid), + accessLevel: pnid.access_level, + titleId: passwordResetToken.info.title_id, + issueTime: passwordResetToken.info.issued, + expireTime: passwordResetToken.info.expires + }, + basicUserInfo: { + // TODO - ban: {} + accessBetaServers: pnid.access_level === 1 || pnid.access_level === 2 || pnid.access_level === 3, // TODO - Remove with a better permission check later + accessDeveloperServers: pnid.access_level === 3 // TODO - Remove with a better permission check later + } + }; +} diff --git a/src/services/grpc/account/v2/exchange-token-for-user-data.ts b/src/services/grpc/account/v2/exchange-token-for-user-data.ts index fef47d9..81e92f2 100644 --- a/src/services/grpc/account/v2/exchange-token-for-user-data.ts +++ b/src/services/grpc/account/v2/exchange-token-for-user-data.ts @@ -2,11 +2,9 @@ import { Status, ServerError } from 'nice-grpc'; import { getPNIDByAPIAccessToken } from '@/database'; import { PNID_PERMISSION_FLAGS } from '@/types/common/permission-flags'; import { config } from '@/config-manager'; -import { Device } from '@/models/device'; -import type { GetUserDataResponse } from '@pretendonetwork/grpc/account/v2/get_user_data_rpc'; -import type { ExchangeTokenForUserDataRequest } from '@pretendonetwork/grpc/account/v2/exchange_token_for_user_data'; +import type { ExchangeTokenForUserDataRequest, ExchangeTokenForUserDataResponse } from '@pretendonetwork/grpc/account/v2/exchange_token_for_user_data_rpc'; -export async function exchangeTokenForUserData(request: ExchangeTokenForUserDataRequest): Promise { +export async function exchangeTokenForUserData(request: ExchangeTokenForUserDataRequest): Promise { if (!request.token.trim()) { throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); } @@ -17,20 +15,8 @@ export async function exchangeTokenForUserData(request: ExchangeTokenForUserData throw new ServerError(Status.INVALID_ARGUMENT, 'Invalid token'); } - const devices = (await Device.find({ - linked_pids: pnid.pid - })).map((device) => { - return { - model: device.get('model'), // ".model" gives the Mongoose model... - serial: device.serial, - linkedPids: device.linked_pids, - accessLevel: device.access_level, - serverAccessLevel: device.server_access_level - }; - }); - return { - deleted: pnid.deleted, + deleted: pnid.deleted || pnid.marked_for_deletion, pid: pnid.pid, username: pnid.username, accessLevel: pnid.access_level, @@ -70,7 +56,6 @@ export async function exchangeTokenForUserData(request: ExchangeTokenForUserData updateBossFiles: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPDATE_BOSS_FILES), deleteBossFiles: pnid.hasPermission(PNID_PERMISSION_FLAGS.DELETE_BOSS_FILES), updatePnidPermissions: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPDATE_PNID_PERMISSIONS) - }, - linkedDevices: devices + } }; } diff --git a/src/services/grpc/account/v2/get-ban.ts b/src/services/grpc/account/v2/get-ban.ts new file mode 100644 index 0000000..746e49a --- /dev/null +++ b/src/services/grpc/account/v2/get-ban.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { GetBanRequest, GetBanResponse } from '@pretendonetwork/grpc/account/v2/get_ban_rpc'; + +export async function getBan(_request: GetBanRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/get-device.ts b/src/services/grpc/account/v2/get-device.ts new file mode 100644 index 0000000..e116c2f --- /dev/null +++ b/src/services/grpc/account/v2/get-device.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { GetDeviceRequest, GetDeviceResponse } from '@pretendonetwork/grpc/account/v2/get_device_rpc'; + +export async function getDevice(_request: GetDeviceRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/get-nex-account.ts b/src/services/grpc/account/v2/get-nex-account.ts new file mode 100644 index 0000000..ea810e6 --- /dev/null +++ b/src/services/grpc/account/v2/get-nex-account.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { GetNEXAccountRequest, GetNEXAccountResponse } from '@pretendonetwork/grpc/account/v2/get_nex_account_rpc'; + +export async function getNEXAccount(_request: GetNEXAccountRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/get-pnid.ts b/src/services/grpc/account/v2/get-pnid.ts new file mode 100644 index 0000000..075bfe5 --- /dev/null +++ b/src/services/grpc/account/v2/get-pnid.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { GetPNIDRequest, GetPNIDResponse } from '@pretendonetwork/grpc/account/v2/get_pnid_rpc'; + +export async function getPNID(_request: GetPNIDRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/get-pnids.ts b/src/services/grpc/account/v2/get-pnids.ts new file mode 100644 index 0000000..760600f --- /dev/null +++ b/src/services/grpc/account/v2/get-pnids.ts @@ -0,0 +1,75 @@ +import { getPNIDByPID } from '@/database'; +import { PNID_PERMISSION_FLAGS } from '@/types/common/permission-flags'; +import { config } from '@/config-manager'; +import { Device } from '@/models/device'; +import type { GetPNIDsRequest, GetPNIDsResponse } from '@pretendonetwork/grpc/account/v2/get_pnids_rpc'; + +export async function getPNIDs(request: GetPNIDsRequest): Promise { + const response: GetPNIDsResponse = { userData: [] }; + for (const pid of request.pid) { + const pnid = await getPNIDByPID(pid); + if (!pnid) { + continue; + } + + const devices = (await Device.find({ + linked_pids: pnid.pid + })).map((device) => { + return { + model: device.get('model'), // ".model" gives the Mongoose model... + serial: device.serial, + linkedPids: device.linked_pids, + accessLevel: device.access_level, + serverAccessLevel: device.server_access_level, + deviceId: device.device_id + }; + }); + + response.userData[pid] = { + deleted: pnid.deleted || pnid.marked_for_deletion, + pid: pnid.pid, + username: pnid.username, + accessLevel: pnid.access_level, + serverAccessLevel: pnid.server_access_level, + mii: { + name: pnid.mii.name, + data: pnid.mii.data, + url: `${config.cdn.base_url}/mii/${pnid.pid}/standard.tga` + }, + creationDate: pnid.creation_date, + birthdate: pnid.birthdate, + gender: pnid.gender, + country: pnid.country, + language: pnid.language, + emailAddress: pnid.email.address, + tierName: pnid.connections.stripe.tier_name, + permissions: { + bannedAllPermanently: pnid.hasPermission(PNID_PERMISSION_FLAGS.BANNED_ALL_PERMANENTLY), + bannedAllTemporarily: pnid.hasPermission(PNID_PERMISSION_FLAGS.BANNED_ALL_TEMPORARILY), + betaAccess: pnid.hasPermission(PNID_PERMISSION_FLAGS.BETA_ACCESS), + accessAdminPanel: pnid.hasPermission(PNID_PERMISSION_FLAGS.ACCESS_ADMIN_PANEL), + createServerConfigs: pnid.hasPermission(PNID_PERMISSION_FLAGS.CREATE_SERVER_CONFIGS), + modifyServerConfigs: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_SERVER_CONFIGS), + deployServer: pnid.hasPermission(PNID_PERMISSION_FLAGS.DEPLOY_SERVER), + modifyPnids: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_PNIDS), + modifyNexAccounts: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_NEX_ACCOUNTS), + modifyConsoles: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODIFY_CONSOLES), + banPnids: pnid.hasPermission(PNID_PERMISSION_FLAGS.BAN_PNIDS), + banNexAccounts: pnid.hasPermission(PNID_PERMISSION_FLAGS.BAN_NEX_ACCOUNTS), + banConsoles: pnid.hasPermission(PNID_PERMISSION_FLAGS.BAN_CONSOLES), + moderateMiiverse: pnid.hasPermission(PNID_PERMISSION_FLAGS.MODERATE_MIIVERSE), + createApiKeys: pnid.hasPermission(PNID_PERMISSION_FLAGS.CREATE_API_KEYS), + createBossTasks: pnid.hasPermission(PNID_PERMISSION_FLAGS.CREATE_BOSS_TASKS), + updateBossTasks: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPDATE_BOSS_TASKS), + deleteBossTasks: pnid.hasPermission(PNID_PERMISSION_FLAGS.DELETE_BOSS_TASKS), + uploadBossFiles: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPLOAD_BOSS_FILES), + updateBossFiles: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPDATE_BOSS_FILES), + deleteBossFiles: pnid.hasPermission(PNID_PERMISSION_FLAGS.DELETE_BOSS_FILES), + updatePnidPermissions: pnid.hasPermission(PNID_PERMISSION_FLAGS.UPDATE_PNID_PERMISSIONS) + }, + linkedDevices: devices + }; + } + + return response; +} diff --git a/src/services/grpc/account/v2/get-server.ts b/src/services/grpc/account/v2/get-server.ts new file mode 100644 index 0000000..0e2b9c8 --- /dev/null +++ b/src/services/grpc/account/v2/get-server.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { GetServerRequest, GetServerResponse } from '@pretendonetwork/grpc/account/v2/get_server_rpc'; + +export async function getServer(_request: GetServerRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/get-user-data.ts b/src/services/grpc/account/v2/get-user-data.ts index 0cb8f4e..fe08a73 100644 --- a/src/services/grpc/account/v2/get-user-data.ts +++ b/src/services/grpc/account/v2/get-user-data.ts @@ -19,6 +19,7 @@ export async function getUserData(request: GetUserDataRequest): Promise { return { + deviceId: device.device_id, model: device.get('model'), // ".model" gives the Mongoose model... serial: device.serial, linkedPids: device.linked_pids, @@ -28,7 +29,7 @@ export async function getUserData(request: GetUserDataRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/list-audit-log-comments.ts b/src/services/grpc/account/v2/list-audit-log-comments.ts new file mode 100644 index 0000000..95616e3 --- /dev/null +++ b/src/services/grpc/account/v2/list-audit-log-comments.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { ListAuditLogCommentsRequest, ListAuditLogCommentsResponse } from '@pretendonetwork/grpc/account/v2/list_audit_log_comments_rpc'; + +export async function listAuditLogComments(_request: ListAuditLogCommentsRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/list-audit-logs.ts b/src/services/grpc/account/v2/list-audit-logs.ts new file mode 100644 index 0000000..813ec00 --- /dev/null +++ b/src/services/grpc/account/v2/list-audit-logs.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { ListAuditLogsRequest, ListAuditLogsResponse } from '@pretendonetwork/grpc/account/v2/list_audit_logs_rpc'; + +export async function listAuditLogs(_request: ListAuditLogsRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/list-ban-comments.ts b/src/services/grpc/account/v2/list-ban-comments.ts new file mode 100644 index 0000000..45ab08a --- /dev/null +++ b/src/services/grpc/account/v2/list-ban-comments.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { ListBanCommentsRequest, ListBanCommentsResponse } from '@pretendonetwork/grpc/account/v2/list_ban_comments_rpc'; + +export async function listBanComments(_request: ListBanCommentsRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/list-bans.ts b/src/services/grpc/account/v2/list-bans.ts new file mode 100644 index 0000000..c438f49 --- /dev/null +++ b/src/services/grpc/account/v2/list-bans.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { ListBansRequest, ListBansResponse } from '@pretendonetwork/grpc/account/v2/list_bans_rpc'; + +export async function listBans(_request: ListBansRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/list-devices.ts b/src/services/grpc/account/v2/list-devices.ts new file mode 100644 index 0000000..1b3b956 --- /dev/null +++ b/src/services/grpc/account/v2/list-devices.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { ListDevicesRequest, ListDevicesResponse } from '@pretendonetwork/grpc/account/v2/list_devices_rpc'; + +export async function listDevices(_request: ListDevicesRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/list-nex-accounts.ts b/src/services/grpc/account/v2/list-nex-accounts.ts new file mode 100644 index 0000000..5575a8c --- /dev/null +++ b/src/services/grpc/account/v2/list-nex-accounts.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { ListNEXAccountsRequest, ListNEXAccountsResponse } from '@pretendonetwork/grpc/account/v2/list_nex_accounts_rpc'; + +export async function listNEXAccounts(_request: ListNEXAccountsRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/list-pnids.ts b/src/services/grpc/account/v2/list-pnids.ts new file mode 100644 index 0000000..50e6f8e --- /dev/null +++ b/src/services/grpc/account/v2/list-pnids.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { ListPNIDsRequest, ListPNIDsResponse } from '@pretendonetwork/grpc/account/v2/list_pnids_rpc'; + +export async function listPNIDs(_request: ListPNIDsRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/list-servers.ts b/src/services/grpc/account/v2/list-servers.ts new file mode 100644 index 0000000..98ba3a6 --- /dev/null +++ b/src/services/grpc/account/v2/list-servers.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { ListServersRequest, ListServersResponse } from '@pretendonetwork/grpc/account/v2/list_servers_rpc'; + +export async function listServers(_request: ListServersRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/pardon-ban.ts b/src/services/grpc/account/v2/pardon-ban.ts new file mode 100644 index 0000000..050d184 --- /dev/null +++ b/src/services/grpc/account/v2/pardon-ban.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { PardonBanRequest, PardonBanResponse } from '@pretendonetwork/grpc/account/v2/pardon_ban_rpc'; + +export async function pardonBan(_request: PardonBanRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/update-ban.ts b/src/services/grpc/account/v2/update-ban.ts new file mode 100644 index 0000000..82363ce --- /dev/null +++ b/src/services/grpc/account/v2/update-ban.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { UpdateBanRequest, UpdateBanResponse } from '@pretendonetwork/grpc/account/v2/update_ban_rpc'; + +export async function updateBan(_request: UpdateBanRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/update-device.ts b/src/services/grpc/account/v2/update-device.ts new file mode 100644 index 0000000..bb84801 --- /dev/null +++ b/src/services/grpc/account/v2/update-device.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { UpdateDeviceRequest, UpdateDeviceResponse } from '@pretendonetwork/grpc/account/v2/update_device_rpc'; + +export async function updateDevice(_request: UpdateDeviceRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/update-nex-account.ts b/src/services/grpc/account/v2/update-nex-account.ts new file mode 100644 index 0000000..c228a24 --- /dev/null +++ b/src/services/grpc/account/v2/update-nex-account.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { UpdateNEXAccountRequest, UpdateNEXAccountResponse } from '@pretendonetwork/grpc/account/v2/update_nex_account_rpc'; + +export async function updateNEXAccount(_request: UpdateNEXAccountRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/update-pnid-permissions.ts b/src/services/grpc/account/v2/update-pnid-permissions.ts index 075d812..7c35031 100644 --- a/src/services/grpc/account/v2/update-pnid-permissions.ts +++ b/src/services/grpc/account/v2/update-pnid-permissions.ts @@ -1,10 +1,9 @@ import { Status, ServerError } from 'nice-grpc'; import { getPNIDByPID } from '@/database'; import { PNID_PERMISSION_FLAGS } from '@/types/common/permission-flags'; -import type { UpdatePNIDPermissionsRequest } from '@pretendonetwork/grpc/account/v2/update_pnid_permissions'; -import type { Empty } from '@pretendonetwork/grpc/google/protobuf/empty'; +import type { UpdatePNIDPermissionsRequest, UpdatePNIDPermissionsResponse } from '@pretendonetwork/grpc/account/v2/update_pnid_permissions_rpc'; -export async function updatePNIDPermissions(request: UpdatePNIDPermissionsRequest): Promise { +export async function updatePNIDPermissions(request: UpdatePNIDPermissionsRequest): Promise { const pnid = await getPNIDByPID(request.pid); if (!pnid) { diff --git a/src/services/grpc/account/v2/update-pnid.ts b/src/services/grpc/account/v2/update-pnid.ts new file mode 100644 index 0000000..d54d719 --- /dev/null +++ b/src/services/grpc/account/v2/update-pnid.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { UpdatePNIDRequest, UpdatePNIDResponse } from '@pretendonetwork/grpc/account/v2/update_pnid_rpc'; + +export async function updatePNID(_request: UpdatePNIDRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/update-server.ts b/src/services/grpc/account/v2/update-server.ts new file mode 100644 index 0000000..0439c35 --- /dev/null +++ b/src/services/grpc/account/v2/update-server.ts @@ -0,0 +1,9 @@ +import { Status, ServerError } from 'nice-grpc'; +import type { UpdateServerRequest, UpdateServerResponse } from '@pretendonetwork/grpc/account/v2/update_server_rpc'; + +export async function updateServer(_request: UpdateServerRequest): Promise { + throw new ServerError( + Status.UNIMPLEMENTED, + 'Stubbed' + ); +} diff --git a/src/services/grpc/account/v2/validate-independent-service-token.ts b/src/services/grpc/account/v2/validate-independent-service-token.ts new file mode 100644 index 0000000..f5c1753 --- /dev/null +++ b/src/services/grpc/account/v2/validate-independent-service-token.ts @@ -0,0 +1,86 @@ +import crypto from 'node:crypto'; +import { Status, ServerError } from 'nice-grpc'; +import { Server } from '@/models/server'; +import { PNID } from '@/models/pnid'; +import { NEXAccount } from '@/models/nex-account'; +import type { ValidateIndependentServiceTokenRequest, ValidateIndependentServiceTokenResponse } from '@pretendonetwork/grpc/account/v2/validate_independent_service_token_rpc'; +import type { HydratedServerDocument } from '@/types/mongoose/server'; + +export async function validateIndependentServiceToken(request: ValidateIndependentServiceTokenRequest): Promise { + if (request.clientIds.length === 0) { + throw new ServerError(Status.INVALID_ARGUMENT, 'No server identification data sent'); + } + + let server: HydratedServerDocument | null = null; + try { + server = await Server.findOne({ + client_id: { + $in: request.clientIds + } + }); + } catch { + return { + isValid: false + }; + } + + if (!server) { + return { + isValid: false + }; + } + + const token = Buffer.from(request.token, 'hex'); + + if (token.length !== 60) { + return { + isValid: false + }; + } + + const tokenBody = token.subarray(0, 28); + const expectedHMAC = token.subarray(28); + const calculatedHMAC = crypto.createHmac('sha256', server.aes_key).update(tokenBody).digest(); + + if (!crypto.timingSafeEqual(expectedHMAC, calculatedHMAC)) { + return { + isValid: false + }; + } + + // TODO - Add ban lookups once bans are no longer stubbed + const pid = tokenBody.readUInt32BE(0); + + const nexAccount = await NEXAccount.findOne({ + pid: pid + }); + + if (!nexAccount) { + return { + isValid: false + }; + } + + const pnid = await PNID.findOne({ + pid: pid + }); + + if (pnid) { + return { + isValid: true, + basicUserInfo: { + // TODO - ban: {} + accessBetaServers: pnid.access_level === 1 || pnid.access_level === 2 || pnid.access_level === 3, // TODO - Remove with a better permission check later + accessDeveloperServers: pnid.access_level === 3 // TODO - Remove with a better permission check later + } + }; + } else { + return { + isValid: true, + basicUserInfo: { + accessBetaServers: nexAccount.access_level === 1 || nexAccount.access_level === 2 || nexAccount.access_level === 3, // TODO - Remove with a better permission check later + accessDeveloperServers: nexAccount.access_level === 3 // TODO - Remove with a better permission check later + } + }; + } +} diff --git a/src/services/grpc/api/v1/get-user-data.ts b/src/services/grpc/api/v1/get-user-data.ts index 29a78bc..435c349 100644 --- a/src/services/grpc/api/v1/get-user-data.ts +++ b/src/services/grpc/api/v1/get-user-data.ts @@ -9,7 +9,7 @@ export async function getUserData(_request: Empty, context: CallContext & Authen const pnid = context.pnid!; return { - deleted: pnid.deleted, + deleted: pnid.deleted || pnid.marked_for_deletion, creationDate: pnid.creation_date, updatedDate: pnid.updated, pid: pnid.pid, diff --git a/src/services/grpc/api/v1/login.ts b/src/services/grpc/api/v1/login.ts index ecc7a11..c9101f3 100644 --- a/src/services/grpc/api/v1/login.ts +++ b/src/services/grpc/api/v1/login.ts @@ -1,10 +1,11 @@ +import crypto from 'node:crypto'; import { Status, ServerError } from 'nice-grpc'; import bcrypt from 'bcrypt'; import { getPNIDByUsername, getPNIDByAPIRefreshToken } from '@/database'; -import { nintendoPasswordHash, generateToken } from '@/util'; +import { nintendoPasswordHash } from '@/util'; +import { OAuthToken } from '@/models/oauth-token'; import { SystemType } from '@/types/common/system-types'; import { TokenType } from '@/types/common/token-types'; -import { config } from '@/config-manager'; import type { LoginRequest, LoginResponse, DeepPartial } from '@pretendonetwork/grpc/api/login_rpc'; import type { HydratedPNIDDocument } from '@/types/mongoose/pnid'; @@ -52,35 +53,40 @@ export async function login(request: LoginRequest): Promise => { - const requestParams: NASCRequestParams = request.body; +router.post('/', nascRatelimit, async (request: express.Request, response: express.Response): Promise => { + const requestParams: NASCACRequestParams = request.body; const action = nintendoBase64Decode(requestParams.action).toString(); const titleID = nintendoBase64Decode(requestParams.titleid).toString(); const gameServerID = nintendoBase64Decode(requestParams.gameid).toString(); @@ -61,60 +65,72 @@ router.post('/', async (request: express.Request, response: express.Response): P switch (action) { case 'LOGIN': - responseData = await processLoginRequest(server, nexAccount.pid, titleID); + responseData = await processLoginRequest(server, nexAccount.pid, requestParams as NASCLoginACRequestParams); // TODO - Remove this "as" with field checking break; case 'SVCLOC': - responseData = await processServiceTokenRequest(server, nexAccount.pid, titleID); + responseData = await processServiceTokenRequest(server, nexAccount.pid, requestParams as NASCServiceTokenACRequestParams); // TODO - Remove this "as" with field checking break; } response.status(200).send(responseData.toString()); }); -async function processLoginRequest(server: HydratedServerDocument, pid: number, titleID: string): Promise { - const tokenOptions = { - system_type: SystemType.CTR, - token_type: TokenType.NEX, +async function processLoginRequest(server: HydratedServerDocument, pid: number, requestParams: NASCLoginACRequestParams): Promise { + const titleID = nintendoBase64Decode(requestParams.titleid).toString(); + const token = nintendoBase64Encode(crypto.randomBytes(112)); + + await NEXToken.create({ + token: crypto.createHash('sha256').update(token).digest('hex'), + game_server_id: server.game_server_id, pid: pid, - access_level: 0, - title_id: BigInt(parseInt(titleID, 16)), - expire_time: BigInt(Date.now() + (3600 * 1000)) - }; - - // TODO - Handle null tokens - - const nexTokenBuffer = await generateToken(server.aes_key, tokenOptions); - const nexToken = nintendoBase64Encode(nexTokenBuffer || ''); + info: { + system_type: SystemType.CTR, + token_type: TokenType.NEX, + title_id: BigInt(parseInt(titleID, 16)), + issued: new Date(), + expires: new Date(Date.now() + (3600 * 1000)) + } + }); const connectInfo = await server.getServerConnectInfo(); return new URLSearchParams({ locator: nintendoBase64Encode(`${connectInfo.ip}:${connectInfo.port}`), retry: nintendoBase64Encode('0'), returncd: nintendoBase64Encode('001'), - token: nexToken, + token: token, datetime: nintendoBase64Encode(nascDateTime()) }); } -async function processServiceTokenRequest(server: HydratedServerDocument, pid: number, titleID: string): Promise { - const tokenOptions = { - system_type: SystemType.CTR, - token_type: TokenType.IndependentService, +async function processServiceTokenRequest(server: HydratedServerDocument, pid: number, requestParams: NASCServiceTokenACRequestParams): Promise { + const titleID = nintendoBase64Decode(requestParams.titleid).toString(); + const serviceTokenOptions = { pid: pid, - access_level: 0, - title_id: BigInt(parseInt(titleID, 16)), - expire_time: BigInt(Date.now()) // TODO - Hack. Independent services expire their own tokens, so we give them the ISSUED time, not an EXPIRE time + title_id: titleID, + issued: new Date(), + expires: new Date(Date.now() + 24 * 3600 * 1000) }; - // TODO - Handle null tokens + const token = nintendoBase64Encode(createServiceToken(server, serviceTokenOptions)); - const serviceTokenBuffer = await generateToken(server.aes_key, tokenOptions); - const serviceToken = nintendoBase64Encode(serviceTokenBuffer || ''); + await IndependentServiceToken.create({ + token: crypto.createHash('sha256').update(token).digest('hex'), + client_id: nintendoBase64Decode(requestParams.keyhash).toString(), + title_id: serviceTokenOptions.title_id, + pid: serviceTokenOptions.pid, + info: { + system_type: SystemType.CTR, + token_type: TokenType.IndependentService, + title_id: BigInt(parseInt(titleID, 16)), + issued: serviceTokenOptions.issued, + expires: serviceTokenOptions.expires + } + }); return new URLSearchParams({ retry: nintendoBase64Encode('0'), returncd: nintendoBase64Encode('007'), - servicetoken: serviceToken, + servicetoken: token, statusdata: nintendoBase64Encode('Y'), svchost: nintendoBase64Encode('n/a'), datetime: nintendoBase64Encode(nascDateTime()) diff --git a/src/services/nnas/routes/account-settings.ts b/src/services/nnas/routes/account-settings.ts index 3d614d2..8162ac4 100644 --- a/src/services/nnas/routes/account-settings.ts +++ b/src/services/nnas/routes/account-settings.ts @@ -4,14 +4,14 @@ import got from 'got'; import { z } from 'zod'; import { getServerByClientID, getPNIDByPID } from '@/database'; import { LOG_ERROR } from '@/logger'; -import { decryptToken, unpackToken, getValueFromHeaders, sendConfirmationEmail } from '@/util'; +import { getValueFromHeaders, sendConfirmationEmail } from '@/util'; import { config } from '@/config-manager'; +import { IndependentServiceToken } from '@/models/independent-service-token'; import timezones from '@/services/nnas/timezones.json'; import regionsList from '@/services/nnas/regions.json'; import type { HydratedServerDocument } from '@/types/mongoose/server'; import type { HydratedPNIDDocument } from '@/types/mongoose/pnid'; import type { AccountSettings } from '@/types/services/nnas/account-settings'; -import type { Token } from '@/types/common/token'; import type { RegionLanguages } from '@/types/services/nnas/region-languages'; import type { RegionTimezone, RegionTimezones } from '@/types/services/nnas/region-timezones'; import type { Country, Region } from '@/types/services/nnas/regions'; @@ -44,13 +44,22 @@ router.get('/ui/profile', async function (request: express.Request, response: ex return; } - const aes_key: string = server?.aes_key; - const decryptedToken = decryptToken(Buffer.from(token, 'base64'), aes_key); + const serviceToken = await IndependentServiceToken.findOne({ + token: crypto.createHash('sha256').update(token).digest('hex') + }); - const tokenContents: Token = unpackToken(decryptedToken); + if (!serviceToken) { + response.sendStatus(504); + return; + } + + if (serviceToken.client_id !== '3f3928cc6f780638d360f0485cef973f') { + response.sendStatus(504); + return; + } try { - const PNID: HydratedPNIDDocument | null = await getPNIDByPID(tokenContents.pid); + const PNID: HydratedPNIDDocument | null = await getPNIDByPID(serviceToken.pid); if (!PNID) { response.sendStatus(504); @@ -127,12 +136,22 @@ router.post('/update', async function (request: express.Request, response: expre return; } - const aesKey = server?.aes_key; - const decryptedToken = decryptToken(Buffer.from(token, 'base64'), aesKey); - const tokenContents: Token = unpackToken(decryptedToken); + const serviceToken = await IndependentServiceToken.findOne({ + token: crypto.createHash('sha256').update(token).digest('hex') + }); + + if (!serviceToken) { + response.sendStatus(504); + return; + } + + if (serviceToken.client_id !== '3f3928cc6f780638d360f0485cef973f') { + response.sendStatus(504); + return; + } try { - const pnid: HydratedPNIDDocument | null = await getPNIDByPID(tokenContents.pid); + const pnid: HydratedPNIDDocument | null = await getPNIDByPID(serviceToken.pid); const personBody: AccountSettings = request.body; if (!pnid) { diff --git a/src/services/nnas/routes/oauth.ts b/src/services/nnas/routes/oauth.ts index 23f135c..9b95d8e 100644 --- a/src/services/nnas/routes/oauth.ts +++ b/src/services/nnas/routes/oauth.ts @@ -1,14 +1,15 @@ +import crypto from 'node:crypto'; import express from 'express'; import xmlbuilder from 'xmlbuilder'; import bcrypt from 'bcrypt'; import deviceCertificateMiddleware from '@/middleware/device-certificate'; import consoleStatusVerificationMiddleware from '@/middleware/console-status-verification'; import { getPNIDByNNASRefreshToken, getPNIDByUsername } from '@/database'; -import { generateToken } from '@/util'; import { SystemType } from '@/types/common/system-types'; import { TokenType } from '@/types/common/token-types'; -import { config } from '@/config-manager'; import { Device } from '@/models/device'; +import { OAuthToken } from '@/models/oauth-token'; +import { loginRatelimit } from '@/middleware/ratelimit'; const router = express.Router(); @@ -17,7 +18,7 @@ const router = express.Router(); * Replacement for: https://account.nintendo.net/v1/api/oauth20/access_token/generate * Description: Generates an access token for a user */ -router.post('/access_token/generate', deviceCertificateMiddleware, consoleStatusVerificationMiddleware, async (request: express.Request, response: express.Response): Promise => { +router.post('/access_token/generate', loginRatelimit, deviceCertificateMiddleware, consoleStatusVerificationMiddleware, async (request: express.Request, response: express.Response): Promise => { const grantType = request.body.grant_type; const username = request.body.user_id; const password = request.body.password; @@ -128,7 +129,7 @@ router.post('/access_token/generate', deviceCertificateMiddleware, consoleStatus } } - if (pnid.deleted) { + if (pnid.deleted || pnid.marked_for_deletion) { // * 0112 is the "account deleted" error, but unsure if this unlinks the PNID from the user? // * 0143 is the "The link to this Nintendo Network ID has been temporarliy removed" error, // * maybe that is a better error to use here? @@ -167,25 +168,39 @@ router.post('/access_token/generate', deviceCertificateMiddleware, consoleStatus return; } - const accessTokenOptions = { - system_type: SystemType.WUP, - token_type: TokenType.OAuthAccess, + const clientID = request.header('x-nintendo-client-id'); + const clientSecret = request.header('x-nintendo-client-secret'); + + const accessToken = crypto.randomBytes(16).toString('hex'); + const newRefreshToken = crypto.randomBytes(20).toString('hex'); + + await OAuthToken.create({ + token: crypto.createHash('sha256').update(accessToken).digest('hex'), + client_id: clientID, + client_secret: clientSecret, pid: pnid.pid, - expire_time: BigInt(Date.now() + (3600 * 1000)) - }; + info: { + system_type: SystemType.WUP, + token_type: TokenType.OAuthAccess, + title_id: BigInt(0), // TODO - Add this? + issued: new Date(), + expires: new Date(Date.now() + (3600 * 1000)) + } + }); - const refreshTokenOptions = { - system_type: SystemType.WUP, - token_type: TokenType.OAuthRefresh, + await OAuthToken.create({ + token: crypto.createHash('sha256').update(newRefreshToken).digest('hex'), + client_id: clientID, + client_secret: clientSecret, pid: pnid.pid, - expire_time: BigInt(Date.now() + 12 * 3600 * 1000) - }; - - const accessTokenBuffer = await generateToken(config.aes_key, accessTokenOptions); - const refreshTokenBuffer = await generateToken(config.aes_key, refreshTokenOptions); - - const accessToken = accessTokenBuffer ? accessTokenBuffer.toString('hex') : ''; - const newRefreshToken = refreshTokenBuffer ? refreshTokenBuffer.toString('hex') : ''; + info: { + system_type: SystemType.WUP, + token_type: TokenType.OAuthRefresh, + title_id: BigInt(0), // TODO - Add this? + issued: new Date(), + expires: new Date(Date.now() + 12 * 3600 * 1000) + } + }); // TODO - Handle null tokens diff --git a/src/services/nnas/routes/people.ts b/src/services/nnas/routes/people.ts index 01d651c..476ac9e 100644 --- a/src/services/nnas/routes/people.ts +++ b/src/services/nnas/routes/people.ts @@ -4,7 +4,7 @@ import xmlbuilder from 'xmlbuilder'; import bcrypt from 'bcrypt'; import moment from 'moment'; import deviceCertificateMiddleware from '@/middleware/device-certificate'; -import ratelimit from '@/middleware/ratelimit'; +import { deviceRatelimit } from '@/middleware/ratelimit'; import { connection as databaseConnection, doesPNIDExist, getPNIDProfileJSONByPID } from '@/database'; import { getAgeFromDate, getValueFromHeaders, nintendoPasswordHash, sendConfirmationEmail, sendPNIDDeletedEmail } from '@/util'; import IP2LocationManager from '@/ip2location'; @@ -49,7 +49,7 @@ router.get('/:username', async (request: express.Request, response: express.Resp * Replacement for: https://account.nintendo.net/v1/api/people * Description: Registers a new NNID */ -router.post('/', ratelimit, deviceCertificateMiddleware, async (request: express.Request, response: express.Response): Promise => { +router.post('/', deviceRatelimit, deviceCertificateMiddleware, async (request: express.Request, response: express.Response): Promise => { if (!request.certificate || !request.certificate.valid) { // TODO - Change this to a different error response.status(400).send(xmlbuilder.create({ @@ -89,6 +89,25 @@ router.post('/', ratelimit, deviceCertificateMiddleware, async (request: express } } + if (age < 13) { + // * Wii U firmware 5.5.6 changed NNID setup to block setup of new accounts if the users age is + // * under 13, telling parents that they MUST call Nintendo to create the account, and we trusted + // * that users would be on these firmwares. Lower firmwares won't have this though, and will use + // * the old "COPPA approval" system + // * + // * Just block it all the time though, we don't want to deal with this headache + response.status(400).send(xmlbuilder.create({ + errors: { + error: { + code: '0114', + message: 'COPPA approval is not complete' + } + } + }).end()); + + return; + } + const userExists = await doesPNIDExist(person.user_id); if (userExists) { @@ -561,8 +580,7 @@ router.post('/@me/deletion', async (request: express.Request, response: express. const email = pnid.email.address; - await pnid.scrub(); - await pnid.save(); + await pnid.markForDeletion(); try { await sendPNIDDeletedEmail(email, pnid.username); @@ -632,6 +650,8 @@ router.put('/@me', async (request: express.Request, response: express.Response): const passwordHash = await bcrypt.hash(primaryPasswordHash, 10); pnid.password = passwordHash; + + await pnid.removeAllTokens(); } pnid.gender = gender; diff --git a/src/services/nnas/routes/provider.ts b/src/services/nnas/routes/provider.ts index f59b1df..f1cdb84 100644 --- a/src/services/nnas/routes/provider.ts +++ b/src/services/nnas/routes/provider.ts @@ -1,8 +1,11 @@ +import crypto from 'node:crypto'; import express from 'express'; import xmlbuilder from 'xmlbuilder'; import { getServerByClientID, getServerByGameServerID } from '@/database'; -import { generateToken, getValueFromHeaders, getValueFromQueryString } from '@/util'; +import { createServiceToken, getValueFromHeaders, getValueFromQueryString } from '@/util'; import { TokenType } from '@/types/common/token-types'; +import { IndependentServiceToken } from '@/models/independent-service-token'; +import { NEXToken } from '@/models/nex-token'; import { NEXAccount } from '@/models/nex-account'; const router = express.Router(); @@ -90,25 +93,32 @@ router.get('/service_token/@me', async (request: express.Request, response: expr return; } - const tokenOptions = { - system_type: server.device, - token_type: TokenType.IndependentService, + const serviceTokenOptions = { pid: pnid.pid, - access_level: pnid.access_level, - title_id: BigInt(parseInt(titleID, 16)), - expire_time: BigInt(Date.now()) // TODO - Hack. Independent services expire their own tokens, so we give them the ISSUED time, not an EXPIRE time + title_id: titleID, + issued: new Date(), + expires: new Date(Date.now() + 24 * 3600 * 1000) }; - const serviceTokenBuffer = await generateToken(server.aes_key, tokenOptions); - let serviceToken = serviceTokenBuffer ? serviceTokenBuffer.toString('base64') : ''; + const token = createServiceToken(server, serviceTokenOptions).toString('base64'); - if (request.isCemu) { - serviceToken = Buffer.from(serviceToken, 'base64').toString('hex'); - } + await IndependentServiceToken.create({ + token: crypto.createHash('sha256').update(token).digest('hex'), + client_id: clientID, + title_id: serviceTokenOptions.title_id, + pid: serviceTokenOptions.pid, + info: { + system_type: server.device, + token_type: TokenType.IndependentService, + title_id: BigInt(parseInt(titleID, 16)), + issued: serviceTokenOptions.issued, + expires: serviceTokenOptions.expires + } + }); response.send(xmlbuilder.create({ service_token: { - token: serviceToken + token: token } }).end()); }); @@ -213,21 +223,20 @@ router.get('/nex_token/@me', async (request: express.Request, response: express. return; } - const tokenOptions = { - system_type: server.device, - token_type: TokenType.NEX, + const token = crypto.randomBytes(36).toString('base64'); + + await NEXToken.create({ + token: crypto.createHash('sha256').update(token).digest('hex'), + game_server_id: gameServerID, pid: pnid.pid, - access_level: pnid.access_level, - title_id: BigInt(parseInt(titleID, 16)), - expire_time: BigInt(Date.now() + (3600 * 1000)) - }; - - const nexTokenBuffer = await generateToken(server.aes_key, tokenOptions); - let nexToken = nexTokenBuffer ? nexTokenBuffer.toString('base64') : ''; - - if (request.isCemu) { - nexToken = Buffer.from(nexToken || '', 'base64').toString('hex'); - } + info: { + system_type: server.device, + token_type: TokenType.NEX, + title_id: BigInt(parseInt(titleID, 16)), + issued: new Date(), + expires: new Date(Date.now() + (3600 * 1000)) + } + }); const connectInfo = await server.getServerConnectInfo(); response.send(xmlbuilder.create({ @@ -236,7 +245,7 @@ router.get('/nex_token/@me', async (request: express.Request, response: express. nex_password: nexAccount.password, pid: nexAccount.pid, port: connectInfo.port, - token: nexToken + token: token } }).end()); }); diff --git a/src/services/nnas/timezones.json b/src/services/nnas/timezones.json index e7ef542..ade0122 100644 --- a/src/services/nnas/timezones.json +++ b/src/services/nnas/timezones.json @@ -1983,7 +1983,7 @@ { "area": "America/Nassau", "language": "en", - "name": "Eastern Time (US & Canada)", + "name": "Eastern Time (US & Canada)", "utc_offset": "-18000", "order": "0" } @@ -2171,14 +2171,14 @@ { "area": "America/Dawson", "language": "en", - "name": "Pacific Time (US & Canada)", + "name": "Pacific Time (US & Canada)", "utc_offset": "-28800", "order": "1" }, { "area": "America/Cambridge_Bay", "language": "en", - "name": "Mountain Time (US & Canada)", + "name": "Mountain Time (US & Canada)", "utc_offset": "-25200", "order": "2" }, @@ -2192,7 +2192,7 @@ { "area": "America/Rainy_River", "language": "en", - "name": "Central Time (US & Canada)", + "name": "Central Time (US & Canada)", "utc_offset": "-21600", "order": "4" }, @@ -2213,7 +2213,7 @@ { "area": "America/Iqaluit", "language": "en", - "name": "Eastern Time (US & Canada)", + "name": "Eastern Time (US & Canada)", "utc_offset": "-18000", "order": "7" }, @@ -5038,7 +5038,7 @@ { "area": "America/Grand_Turk", "language": "en", - "name": "Eastern Time (US & Canada)", + "name": "Eastern Time (US & Canada)", "utc_offset": "-14400", "order": "3" }, @@ -12519,7 +12519,7 @@ { "area": "America/Grand_Turk", "language": "en", - "name": "Eastern Time (US & Canada)", + "name": "Eastern Time (US & Canada)", "utc_offset": "-14400", "order": "0" } @@ -13049,14 +13049,14 @@ { "area": "America/Los_Angeles", "language": "en", - "name": "Pacific Time (US & Canada)", + "name": "Pacific Time (US & Canada)", "utc_offset": "-28800", "order": "5" }, { "area": "America/Boise", "language": "en", - "name": "Mountain Time (US & Canada)", + "name": "Mountain Time (US & Canada)", "utc_offset": "-25200", "order": "6" }, @@ -13070,7 +13070,7 @@ { "area": "America/Chicago", "language": "en", - "name": "Central Time (US & Canada)", + "name": "Central Time (US & Canada)", "utc_offset": "-21600", "order": "8" }, @@ -13091,7 +13091,7 @@ { "area": "America/New_York", "language": "en", - "name": "Eastern Time (US & Canada)", + "name": "Eastern Time (US & Canada)", "utc_offset": "-18000", "order": "11" }, diff --git a/src/types/common/service-token-options.ts b/src/types/common/service-token-options.ts new file mode 100644 index 0000000..4fabbab --- /dev/null +++ b/src/types/common/service-token-options.ts @@ -0,0 +1,6 @@ +export interface ServiceTokenOptions { + pid: number; + title_id: string; + issued: Date; + expires: Date; +} diff --git a/src/types/common/token-options.ts b/src/types/common/token-options.ts deleted file mode 100644 index ca1bdb5..0000000 --- a/src/types/common/token-options.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { SystemType } from '@/types/common/system-types'; -import type { TokenType } from '@/types/common/token-types'; - -export interface TokenOptions { - system_type: SystemType; - token_type: TokenType; - pid: number; - access_level?: number; - title_id?: bigint; - expire_time: bigint; -} diff --git a/src/types/mongoose/pnid.ts b/src/types/mongoose/pnid.ts index 440e23b..17a9194 100644 --- a/src/types/mongoose/pnid.ts +++ b/src/types/mongoose/pnid.ts @@ -4,6 +4,8 @@ import type { PNIDPermissionFlag } from '@/types/common/permission-flags'; export interface IPNID { deleted: boolean; + marked_for_deletion: boolean; + hard_delete_time: Date; permissions: bigint; access_level: number; server_access_level: string; @@ -81,7 +83,9 @@ export interface IPNIDMethods { generateEmailValidationToken(): Promise; updateMii(mii: { name: string; primary: string; data: string }): Promise; generateMiiImages(): Promise; + markForDeletion(): void; scrub(): Promise; + removeAllTokens(): Promise; hasPermission(flag: PNIDPermissionFlag): boolean; addPermission(flag: PNIDPermissionFlag): void; clearPermission(flag: PNIDPermissionFlag): void; diff --git a/src/types/services/api/connection-data.ts b/src/types/services/api/connection-data.ts deleted file mode 100644 index 67d47ce..0000000 --- a/src/types/services/api/connection-data.ts +++ /dev/null @@ -1,4 +0,0 @@ -import type { DiscordConnectionData } from '@/types/services/api/discord-connection-data'; - -// TODO - This will be a union of all ConnectionData types when more connections are added -export type ConnectionData = DiscordConnectionData; diff --git a/src/types/services/api/connection-response.ts b/src/types/services/api/connection-response.ts deleted file mode 100644 index 80e2cab..0000000 --- a/src/types/services/api/connection-response.ts +++ /dev/null @@ -1,5 +0,0 @@ -export interface ConnectionResponse { - app: string; - status: number; - error?: string; -} diff --git a/src/types/services/api/discord-connection-data.ts b/src/types/services/api/discord-connection-data.ts deleted file mode 100644 index 8d08c84..0000000 --- a/src/types/services/api/discord-connection-data.ts +++ /dev/null @@ -1,3 +0,0 @@ -export interface DiscordConnectionData { - id: string; -} diff --git a/src/types/services/nasc/ac-request-params.ts b/src/types/services/nasc/ac-request-params.ts new file mode 100644 index 0000000..6a62c86 --- /dev/null +++ b/src/types/services/nasc/ac-request-params.ts @@ -0,0 +1,216 @@ +/** + * Çommon request parameters found on all NASC `ac` requests. + * All fields are base64 encoded using Nintendo's custom alphabet: + * '+' -> '.', '/' -> '-', '=' -> '*' + */ +export interface NASCCommonACRequestParams { + /** + * Game server ID (`%08X`). This is the same as the `X-GameId` header. + * Derived from the games default title ID (usually the Japanese title ID) + */ + gameid: string; + + /** + * Major and minor SDK version (`%03d%03d`). Always `000000` + */ + sdkver: string; + + /** + * Title ID (`%016X`) + */ + titleid: string; + + /** + * Product code. See https://3dsdb.com/ + */ + gamecd: string; + + /** + * Title version (`%04X`) + */ + gamever: string; + + /** + * Game type + * + * - 0 = System + * - 1 = Digital + * - 2 = Cartridge + */ + mediatype: string; + + /** + * Unique ROM (game) ID. + * Only present if the media type is 2 (cartridge) + */ + romid?: string; + + /** + * Product maker (company code) + */ + makercd: string; + + /** + * Unit code + * + * - 0 = NDS + * - 1 = Wii + * - 2 = 3DS + */ + unitcd: string; + + /** + * Device MAC address + */ + macadr: string; + + /** + * BSSID of active wifi network + */ + bssid: string; + + /** + * Information about the used Wi-Fi access point in the format `AA:BBBBBBBBBB`. + * Example `01:0000000000`. `AA` is the AP slot. `BBBBBBBBBB` comes from either `ACU_GetNZoneApNumService` or `ACU_GetConnectingHotspotSubset` based on the result from `ACU_GetWifiStatus` + */ + apinfo: string; + + /** + * LocalFriendCodeSeed_B + */ + fcdcert: string; + + /** + * Device name (UTF-16-LE) + */ + devname: string; + + /** + * Environment (`L1` for production) + */ + servertype: string; + + /** + * FPD version (`%04X`). This is also included in the user agent. + */ + fpdver: string; + + /** + * Current device time (`%y%m%d%H%M%S`) + */ + devtime: string; + + /** + * Language code (`%02X`) + */ + lang: string; + + /** + * Region code (`%02X`) + */ + region: string; + + /** + * Serial number + */ + csnum: string; + + /** + * The type of action the console wishes to perform: + * + * - LOGIN = Register new game server account or login to existing on + * - SVCLOC = Request service token + * - nzchk = Unknown, but seems related to Nintendo Zone + * - parse = Unknown + * - message = Unknown + */ + action: string; +} + +/** + * Request parameters for when a console wants to register a new game server account. + * See also NASCCommonRequestParams. + * All fields are base64 encoded using Nintendo's custom alphabet: + * '+' -> '.', '/' -> '-', '=' -> '*' + */ +export interface NASCRegistrationACRequestParams extends NASCCommonACRequestParams { + /** + * Game server account password the console wishes to use for the new account. + * Can be any character between `\x21-\x5B` and `\x5D-\x7D`. Always 16 characters long + */ + passwd: string; + + /** + * Nickname provided by game. + * Usually unused, leftover from the Wii + */ + ingamesn: string; +} + +/** + * Request parameters for when a console wants to login to an existing game server account. + * See also NASCCommonRequestParams. + * All fields are base64 encoded using Nintendo's custom alphabet: + * '+' -> '.', '/' -> '-', '=' -> '*' + */ +export interface NASCLoginACRequestParams extends NASCCommonACRequestParams { + /** + * Hash of the user ID + */ + uidhmac: string; + + /** + * Game server account user ID/username. + * Always the NEX account PID on 3DS + */ + userid: string; + + /** + * Nickname provided by game. + * Usually unused, leftover from the Wii + */ + ingamesn: string; +} + +/** + * Request parameters for when a console wants to request a service token. + * See also NASCCommonRequestParams. + * All fields are base64 encoded using Nintendo's custom alphabet: + * '+' -> '.', '/' -> '-', '=' -> '*' + */ +export interface NASCServiceTokenACRequestParams extends NASCCommonACRequestParams { + /** + * Hash of the user ID + */ + uidhmac: string; + + /** + * Game server account user ID/username. + * Always the NEX account PID on 3DS + */ + userid: string; + + /** + * Unique hash assigned to each game, regardless of title ID. + * Analogous to the NNAS client ID + */ + keyhash: string; + + /** + * Service request type. Changes the `svchost` response field. + * This is likely a remnant from the original NAS/NASWII servers. + * + * - 0000 = "n/a" + * - 9001 = "dls1.nintendowifi.net" + */ + svc: string; +} + +/** + * Union type representing all possible NASC request parameter types. + * The specific type used depends on the `action` field value: + * + * - `action: 'LOGIN'` = `NASCRegistrationRequestParams` or `NASCLoginRequestParams` + * - `action: 'SVCLOC'` = `NASCServiceTokenRequestParams` + */ +export type NASCACRequestParams = NASCRegistrationACRequestParams | NASCLoginACRequestParams | NASCServiceTokenACRequestParams; diff --git a/src/types/services/nasc/request-params.ts b/src/types/services/nasc/request-params.ts deleted file mode 100644 index e7e113f..0000000 --- a/src/types/services/nasc/request-params.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface NASCRequestParams { - action: string; - fcdcert: string; - csnum: string; - macadr: string; - titleid: string; - servertype: string; - gameid: string; - userid?: string; - uidhmac?: string; - passwd?: string; -} diff --git a/src/util.ts b/src/util.ts index 41d90ae..fa6da85 100644 --- a/src/util.ts +++ b/src/util.ts @@ -2,21 +2,23 @@ import crypto from 'node:crypto'; import path from 'node:path'; import { S3 } from '@aws-sdk/client-s3'; import fs from 'fs-extra'; -import bufferCrc32 from 'buffer-crc32'; -import { crc32 } from 'crc'; +import { CronJob } from 'cron'; +import { checkMarkedDeletions } from '@/database'; import { sendMail, CreateEmail } from '@/mailer'; import { SystemType } from '@/types/common/system-types'; import { TokenType } from '@/types/common/token-types'; import { config, disabledFeatures } from '@/config-manager'; +import { PasswordResetToken } from '@/models/password-reset-token'; +import { LOG_ERROR } from '@/logger'; +import type { IncomingHttpHeaders } from 'node:http'; import type { ParsedQs } from 'qs'; import type mongoose from 'mongoose'; import type express from 'express'; import type { ObjectCannedACL } from '@aws-sdk/client-s3'; -import type { IncomingHttpHeaders } from 'node:http'; -import type { TokenOptions } from '@/types/common/token-options'; -import type { Token } from '@/types/common/token'; import type { IPNID, IPNIDMethods } from '@/types/mongoose/pnid'; import type { SafeQs } from '@/types/common/safe-qs'; +import type { HydratedServerDocument } from '@/types/mongoose/server'; +import type { ServiceTokenOptions } from '@/types/common/service-token-options'; let s3: S3; @@ -56,98 +58,22 @@ export function nintendoBase64Encode(decoded: string | Buffer): string { return encoded.replaceAll('+', '.').replaceAll('/', '-').replaceAll('=', '*'); } -export function generateToken(key: string, options: TokenOptions): Buffer | null { - let dataBuffer = Buffer.alloc(1 + 1 + 4 + 8); +export function createServiceToken(server: HydratedServerDocument, options: ServiceTokenOptions): Buffer { + const dataBuffer = Buffer.alloc(28); - dataBuffer.writeUInt8(options.system_type, 0x0); - dataBuffer.writeUInt8(options.token_type, 0x1); - dataBuffer.writeUInt32LE(options.pid, 0x2); - dataBuffer.writeBigUInt64LE(options.expire_time, 0x6); + dataBuffer.writeUInt32BE(options.pid, 0); + dataBuffer.writeBigUInt64BE(BigInt(parseInt(options.title_id, 16)), 4); + dataBuffer.writeBigUInt64BE(BigInt(options.issued.getTime()), 12); + dataBuffer.writeBigUInt64BE(BigInt(options.expires.getTime()), 20); - if ((options.token_type !== TokenType.OAuthAccess && options.token_type !== TokenType.OAuthRefresh) || options.system_type === SystemType.API) { - // * Access and refresh tokens have smaller bodies due to size constraints - // * The API does not have this restraint, however - if (options.title_id === undefined || options.access_level === undefined) { - return null; - } + // * Not using AES anymore but fuck it, it's here already + // TODO - rename the AES field + const hmac = crypto.createHmac('sha256', server.aes_key).update(dataBuffer).digest(); - dataBuffer = Buffer.concat([ - dataBuffer, - Buffer.alloc(8 + 1) - ]); - - dataBuffer.writeBigUInt64LE(options.title_id, 0xE); - dataBuffer.writeInt8(options.access_level, 0x16); - } - - const iv = Buffer.alloc(16); - const cipher = crypto.createCipheriv('aes-256-cbc', Buffer.from(key, 'hex'), iv); - - const encrypted = Buffer.concat([ - cipher.update(dataBuffer), - cipher.final() + return Buffer.concat([ + dataBuffer, + hmac ]); - - let final = encrypted; - - if ((options.token_type !== TokenType.OAuthAccess && options.token_type !== TokenType.OAuthRefresh) || options.system_type === SystemType.API) { - // * Access and refresh tokens don't get a checksum due to size constraints - const checksum = bufferCrc32(dataBuffer); - - final = Buffer.concat([ - checksum, - final - ]); - } - - return final; -} - -export function decryptToken(token: Buffer, key?: string): Buffer { - let encryptedBody: Buffer; - let expectedChecksum = 0; - - if (token.length === 16) { - // * Token is an access/refresh token, no checksum - encryptedBody = token; - } else { - expectedChecksum = token.readUint32BE(); - encryptedBody = token.subarray(4); - } - - if (!key) { - key = config.aes_key; - } - - const iv = Buffer.alloc(16); - const decipher = crypto.createDecipheriv('aes-256-cbc', Buffer.from(key, 'hex'), iv); - - const decrypted = Buffer.concat([ - decipher.update(encryptedBody), - decipher.final() - ]); - - if (expectedChecksum && (expectedChecksum !== crc32(decrypted))) { - throw new Error('Checksum did not match. Failed decrypt. Are you using the right key?'); - } - - return decrypted; -} - -export function unpackToken(token: Buffer): Token { - const unpacked: Token = { - system_type: token.readUInt8(0x0), - token_type: token.readUInt8(0x1), - pid: token.readUInt32LE(0x2), - expire_time: token.readBigUInt64LE(0x6) - }; - - if (unpacked.token_type !== TokenType.OAuthAccess && unpacked.token_type !== TokenType.OAuthRefresh) { - unpacked.title_id = token.readBigUInt64LE(0xE); - unpacked.access_level = token.readInt8(0x16); - } - - return unpacked; } export function fullUrl(request: express.Request): string { @@ -248,25 +174,25 @@ export async function sendEmailConfirmedParentalControlsEmail(pnid: mongoose.Hyd } export async function sendForgotPasswordEmail(pnid: mongoose.HydratedDocument): Promise { - const tokenOptions = { - system_type: SystemType.PasswordReset, - token_type: TokenType.PasswordReset, + const token = crypto.randomBytes(36).toString('hex'); + + await PasswordResetToken.create({ + token: crypto.createHash('sha256').update(token).digest('hex'), pid: pnid.pid, - access_level: pnid.access_level, - title_id: BigInt(0), - expire_time: BigInt(Date.now() + (24 * 60 * 60 * 1000)) // * Only valid for 24 hours - }; - - const tokenBuffer = await generateToken(config.aes_key, tokenOptions); - const passwordResetToken = tokenBuffer ? tokenBuffer.toString('hex') : ''; - - // TODO - Handle null token + info: { + system_type: SystemType.PasswordReset, + token_type: TokenType.PasswordReset, + title_id: BigInt(0), + issued: new Date(), + expires: new Date(Date.now() + (24 * 60 * 60 * 1000)) + } + }); const email = new CreateEmail() .addHeader('Dear {{pnid}},', { pnid: pnid.username }) .addParagraph('a password reset has been requested from this account.') .addParagraph('If you did not request the password reset, please ignore this email. If you did request this password reset, please click the link below to reset your password.') - .addButton('Reset password', `${config.website_base}/account/reset-password?token=${encodeURIComponent(passwordResetToken)}`); + .addButton('Reset password', `${config.website_base}/account/reset-password?token=${encodeURIComponent(token)}`); const mailerOptions = { to: pnid.email.address, @@ -278,14 +204,24 @@ export async function sendForgotPasswordEmail(pnid: mongoose.HydratedDocument { + const deletionDate = new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toLocaleString('en-US', { + timeZone: 'UTC', + weekday: 'long', + year: 'numeric', + month: 'long', + day: 'numeric' + }); const email = new CreateEmail() - .addHeader('Dear {{pnid}},', { pnid: username }) - .addParagraph('your PNID has successfully been deleted.') - .addParagraph('If you had a tier subscription, a separate cancellation email will be sent. If you do not receive this cancellation email, or you are still being charged for your subscription, please contact @jonbarrow on our [Discord server](https://discord.pretendo.network/).'); + .addHeader('Dear {{pnid}}.', { pnid: username }) + .addParagraph('Your PNID has been scheduled for deletion.') + .addParagraph(`Your account and related data will be permanently deleted in 7 days (${deletionDate}). Note that this will not free the username associated with the account for use in future accounts.`) + .addParagraph('You may restore your account at any time before the deletion date. To do so, email [restore-account@pretendo.network](mailto:restore-account@pretendo.network?subject=Requesting%20account%20restore&body=Please%20restore%20my%20account) from the email address used to register, with the subject "Requesting account restore" and your PNID username in the body. Requests must be submitted more than 24 hours before the deletion date, as after this point your data may be unrecoverable. For additional help, visit our [Forum](https://forum.pretendo.network/) or [Discord server](https://discord.pretendo.network/).') + .addParagraph('If you have or have had an active tier subscription, your associated Stripe data (including payment info and invoices) will be permanently deleted on the deletion date and cannot be restored.') + .addParagraph('No new charges will be made during the grace period, even if a renewal would normally occur. If your account is restored with an active subscription, you may need to resubscribe. If you notice unexpected charges during the grace period, please contact us via our [Forum](https://forum.pretendo.network/) or [Discord server](https://discord.pretendo.network/) before the deletion date.'); const options = { to: emailAddress, - subject: '[Pretendo Network] PNID Deleted', + subject: '[Pretendo Network] PNID Deletion', email }; @@ -392,3 +328,24 @@ export function getAgeFromDate(dateString: string): number { return age; } + +export async function setupScheduledTasks(): Promise { + scheduledTask('0 2 * * *', 'check-account-deletions', checkMarkedDeletions); +} + +function scheduledTask(schedule: string, name: string, fn: () => void | Promise): void { + CronJob.from({ + cronTime: schedule, + onTick: async () => { + try { + const result = fn(); + await result; + } catch (err) { + LOG_ERROR(`Error in schedule ${name}: ${err}`); + } + }, + start: true + }); + + LOG_ERROR(`Added schedule ${name} for ${schedule}`); +}