From 70e69141739c6f21011b870e4a5025efc5fe81dd Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Tue, 31 Jan 2023 16:35:59 +0100 Subject: [PATCH 01/14] ci: Fix CI not running for certain branches (#8417) --- .github/workflows/ci.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c030722f71..1a4c267503 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,7 +3,8 @@ on: push: branches: [ release*, alpha, beta ] pull_request: - branches: [ release*, alpha, beta ] + branches: + - '**' env: NODE_VERSION: 19.3.0 PARSE_SERVER_TEST_TIMEOUT: 20000 From 8414ad3f3282bc0bb3b43e55396998f4f9a7444d Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 31 Jan 2023 15:37:19 +0000 Subject: [PATCH 02/14] chore(release): 6.0.0-alpha.31 [skip ci] # [6.0.0-alpha.31](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.30...6.0.0-alpha.31) (2023-01-31) ### Bug Fixes * Parse Server option `requestKeywordDenylist` can be bypassed via Cloud Code Webhooks or Triggers; fixes security vulnerability [GHSA-xprv-wvh7-qqqx](https://github.com/parse-community/parse-server/security/advisories/GHSA-xprv-wvh7-qqqx) ([#8302](https://github.com/parse-community/parse-server/issues/8302)) ([6728da1](https://github.com/parse-community/parse-server/commit/6728da1e3591db1e27031d335d64d8f25546a06f)) * Prototype pollution via Cloud Code Webhooks; fixes security vulnerability [GHSA-93vw-8fm5-p2jf](https://github.com/parse-community/parse-server/security/advisories/GHSA-93vw-8fm5-p2jf) ([#8305](https://github.com/parse-community/parse-server/issues/8305)) ([60c5a73](https://github.com/parse-community/parse-server/commit/60c5a73d257e0d536056b38bdafef8b7130524d8)) * Remote code execution via MongoDB BSON parser through prototype pollution; fixes security vulnerability [GHSA-prm5-8g2m-24gg](https://github.com/parse-community/parse-server/security/advisories/GHSA-prm5-8g2m-24gg) ([#8295](https://github.com/parse-community/parse-server/issues/8295)) ([50eed3c](https://github.com/parse-community/parse-server/commit/50eed3cffe80fadfb4bdac52b2783a18da2cfc4f)) --- changelogs/CHANGELOG_alpha.md | 9 +++++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/changelogs/CHANGELOG_alpha.md b/changelogs/CHANGELOG_alpha.md index e7e5890f30..97547c8efa 100644 --- a/changelogs/CHANGELOG_alpha.md +++ b/changelogs/CHANGELOG_alpha.md @@ -1,3 +1,12 @@ +# [6.0.0-alpha.31](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.30...6.0.0-alpha.31) (2023-01-31) + + +### Bug Fixes + +* Parse Server option `requestKeywordDenylist` can be bypassed via Cloud Code Webhooks or Triggers; fixes security vulnerability [GHSA-xprv-wvh7-qqqx](https://github.com/parse-community/parse-server/security/advisories/GHSA-xprv-wvh7-qqqx) ([#8302](https://github.com/parse-community/parse-server/issues/8302)) ([6728da1](https://github.com/parse-community/parse-server/commit/6728da1e3591db1e27031d335d64d8f25546a06f)) +* Prototype pollution via Cloud Code Webhooks; fixes security vulnerability [GHSA-93vw-8fm5-p2jf](https://github.com/parse-community/parse-server/security/advisories/GHSA-93vw-8fm5-p2jf) ([#8305](https://github.com/parse-community/parse-server/issues/8305)) ([60c5a73](https://github.com/parse-community/parse-server/commit/60c5a73d257e0d536056b38bdafef8b7130524d8)) +* Remote code execution via MongoDB BSON parser through prototype pollution; fixes security vulnerability [GHSA-prm5-8g2m-24gg](https://github.com/parse-community/parse-server/security/advisories/GHSA-prm5-8g2m-24gg) ([#8295](https://github.com/parse-community/parse-server/issues/8295)) ([50eed3c](https://github.com/parse-community/parse-server/commit/50eed3cffe80fadfb4bdac52b2783a18da2cfc4f)) + # [6.0.0-alpha.30](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.29...6.0.0-alpha.30) (2023-01-27) diff --git a/package-lock.json b/package-lock.json index db1438192d..09b28d4526 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "parse-server", - "version": "6.0.0-beta.1", + "version": "6.0.0-alpha.31", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "parse-server", - "version": "6.0.0-beta.1", + "version": "6.0.0-alpha.31", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 7d5a1471f1..2b162c0ee2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "parse-server", - "version": "6.0.0-beta.1", + "version": "6.0.0-alpha.31", "description": "An express module providing a Parse-compatible API server", "main": "lib/index.js", "repository": { From 46e2760a46da8fb178dfc87a4e67eebd4a9bcdb2 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Fri, 3 Feb 2023 20:08:30 +0100 Subject: [PATCH 03/14] refactor: Bump http-cache-semantics from 4.1.0 to 4.1.1 (#8422) --- package-lock.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/package-lock.json b/package-lock.json index 09b28d4526..367d50d553 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8892,9 +8892,9 @@ } }, "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true }, "node_modules/http-errors": { @@ -27432,9 +27432,9 @@ } }, "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", "dev": true }, "http-errors": { From 4450ecbc01ab72544997f611e56d16878fc347ef Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Sat, 4 Feb 2023 21:52:28 +0100 Subject: [PATCH 04/14] docs: Add issue scope to contribution guide (#8423) --- CONTRIBUTING.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 29149b9fd4..47c286c8ce 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -3,6 +3,7 @@ ## Table of Contents - [Contributing](#contributing) - [Issue vs. Pull Request](#issue-vs-pull-request) + - [Scope](#scope) - [Templates](#templates) - [Why Contributing?](#why-contributing) - [Contribution FAQs](#contribution-faqs) @@ -65,6 +66,14 @@ An issue is required to be linked in every pull request. We understand that no-o - The discussion in the issue is different from the discussion in the pull request. The issue discussion is focused on the issue and how to address it, whereas the discussion in the pull request is focused on a specific implemention. An issue may even have multiple pull requests because either the issue requires multiple implementations or multiple pull requests are opened to compare and test different approaches to later decide for one. - High-level conceptual discussions about the issue should be still available, even if a pull request is closed because its appraoch was discarded. If these discussions are in the pull request instead, they can easily become fragmented over multiple pull requests and issues, which can make it very hard to make sense of all aspects of an issue. +### Scope + +An issue and pull request must limit its scope on a distinct issue. Pull requests can only contain changes that are required to address the scoped issue. While it may seem quick and easy to add unrelated changes to the pull request, it can cause singificant complications after merging. Some of the reasons are: + +- A pull request corresponds to a single changelog entry. A changelog entry should not describe multiple unrelated changes in one entry for better readability. +- A pull request creates a distinct commit; having an individual commit for each limited scope makes it easier for others to go back in the commit history and debug. Bugs are generally more difficult to identify and fix if there are various unrelated changes merged at once. +- If a pull request needs to be reverted, unrelated changes will be reverted as well. That makes it more complex and time consuming to revert, having to consider its effects and possibly publishing a broken release or requiring a follow-up pull request with code manipulation. + ### Templates You are required to use and completely fill out the templates for new issues and pull requests. We understand that no-one enjoys filling out forms, but here is why this is beneficial for everyone: From f5bfe4571e82b2b7440d41f3cff0d49937398164 Mon Sep 17 00:00:00 2001 From: Daniel Date: Tue, 7 Feb 2023 22:45:30 +1100 Subject: [PATCH 05/14] fix: Security upgrade jsonwebtoken to 9.0.0 (#8420) --- package-lock.json | 104 +++++++++++++++++----------- package.json | 2 +- spec/AuthenticationAdapters.spec.js | 53 +++++++------- spec/index.spec.js | 3 +- src/Adapters/Auth/apple.js | 12 +--- src/Adapters/Auth/facebook.js | 12 +--- src/Adapters/Auth/google.js | 13 +--- src/Adapters/Auth/utils.js | 13 ++++ 8 files changed, 114 insertions(+), 98 deletions(-) create mode 100644 src/Adapters/Auth/utils.js diff --git a/package-lock.json b/package-lock.json index 367d50d553..09fb4736c7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -31,7 +31,7 @@ "graphql-tag": "2.12.6", "intersect": "1.0.1", "ip-range-check": "0.2.0", - "jsonwebtoken": "8.5.1", + "jsonwebtoken": "9.0.0", "jwks-rsa": "2.1.5", "ldapjs": "2.3.3", "lodash": "4.17.21", @@ -2863,6 +2863,35 @@ } } }, + "node_modules/@parse/node-apn/node_modules/jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "dependencies": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "engines": { + "node": ">=4", + "npm": ">=1.4.28" + } + }, + "node_modules/@parse/node-apn/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "bin": { + "semver": "bin/semver" + } + }, "node_modules/@parse/node-gcm": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@parse/node-gcm/-/node-gcm-1.0.2.tgz", @@ -10167,32 +10196,18 @@ } }, "node_modules/jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", + "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", "dependencies": { "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", + "lodash": "^4.17.21", "ms": "^2.1.1", - "semver": "^5.6.0" + "semver": "^7.3.8" }, "engines": { - "node": ">=4", - "npm": ">=1.4.28" - } - }, - "node_modules/jsonwebtoken/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "bin": { - "semver": "bin/semver" + "node": ">=12", + "npm": ">=6" } }, "node_modules/jsprim": { @@ -22697,6 +22712,28 @@ "requires": { "ms": "2.1.2" } + }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" } } }, @@ -28397,27 +28434,14 @@ } }, "jsonwebtoken": { - "version": "8.5.1", - "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", - "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", + "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", "requires": { "jws": "^3.2.2", - "lodash.includes": "^4.3.0", - "lodash.isboolean": "^3.0.3", - "lodash.isinteger": "^4.0.4", - "lodash.isnumber": "^3.0.3", - "lodash.isplainobject": "^4.0.6", - "lodash.isstring": "^4.0.1", - "lodash.once": "^4.0.0", + "lodash": "^4.17.21", "ms": "^2.1.1", - "semver": "^5.6.0" - }, - "dependencies": { - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" - } + "semver": "^7.3.8" } }, "jsprim": { diff --git a/package.json b/package.json index 2b162c0ee2..947a197bb5 100644 --- a/package.json +++ b/package.json @@ -40,7 +40,7 @@ "graphql-tag": "2.12.6", "intersect": "1.0.1", "ip-range-check": "0.2.0", - "jsonwebtoken": "8.5.1", + "jsonwebtoken": "9.0.0", "jwks-rsa": "2.1.5", "ldapjs": "2.3.3", "lodash": "4.17.21", diff --git a/spec/AuthenticationAdapters.spec.js b/spec/AuthenticationAdapters.spec.js index a940880cbf..bb89596cef 100644 --- a/spec/AuthenticationAdapters.spec.js +++ b/spec/AuthenticationAdapters.spec.js @@ -648,6 +648,7 @@ describe('instagram auth adapter', () => { describe('google auth adapter', () => { const google = require('../lib/Adapters/Auth/google'); const jwt = require('jsonwebtoken'); + const authUtils = require('../lib/Adapters/Auth/utils'); it('should throw error with missing id_token', async () => { try { @@ -670,7 +671,7 @@ describe('google auth adapter', () => { // it('should throw error if public key used to encode token is not available', async () => { // const fakeDecodedToken = { header: { kid: '789', alg: 'RS256' } }; // try { - // spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + // spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); // await google.validateAuthData({ id: 'the_user_id', id_token: 'the_token' }, {}); // fail(); @@ -689,7 +690,7 @@ describe('google auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); const result = await google.validateAuthData( @@ -705,7 +706,7 @@ describe('google auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); try { @@ -729,7 +730,7 @@ describe('google auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); try { @@ -751,7 +752,7 @@ describe('google auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); try { @@ -1454,6 +1455,7 @@ describe('apple signin auth adapter', () => { const apple = require('../lib/Adapters/Auth/apple'); const jwt = require('jsonwebtoken'); const util = require('util'); + const authUtils = require('../lib/Adapters/Auth/utils'); it('(using client id as string) should throw error with missing id_token', async () => { try { @@ -1488,7 +1490,7 @@ describe('apple signin auth adapter', () => { it('should throw error if public key used to encode token is not available', async () => { const fakeDecodedToken = { header: { kid: '789', alg: 'RS256' } }; try { - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken.header); await apple.validateAuthData( { id: 'the_user_id', token: 'the_token' }, @@ -1510,7 +1512,7 @@ describe('apple signin auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken.header); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; @@ -1527,7 +1529,7 @@ describe('apple signin auth adapter', () => { it('should not verify invalid id_token', async () => { const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; }; @@ -1564,7 +1566,7 @@ describe('apple signin auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; }; @@ -1586,7 +1588,7 @@ describe('apple signin auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; }; @@ -1608,7 +1610,7 @@ describe('apple signin auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; }; @@ -1628,7 +1630,7 @@ describe('apple signin auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; }; @@ -1656,7 +1658,7 @@ describe('apple signin auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; }; @@ -1685,7 +1687,7 @@ describe('apple signin auth adapter', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; }; @@ -1757,7 +1759,7 @@ describe('apple signin auth adapter', () => { sub: 'a_different_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', rsaPublicKey: 'the_rsa_public_key' }; }; @@ -2024,6 +2026,7 @@ describe('facebook limited auth adapter', () => { const facebook = require('../lib/Adapters/Auth/facebook'); const jwt = require('jsonwebtoken'); const util = require('util'); + const authUtils = require('../lib/Adapters/Auth/utils'); // TODO: figure out a way to run this test alongside facebook classic tests xit('(using client id as string) should throw error with missing id_token', async () => { @@ -2062,7 +2065,7 @@ describe('facebook limited auth adapter', () => { header: { kid: '789', alg: 'RS256' }, }; try { - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken.header); await facebook.validateAuthData( { id: 'the_user_id', token: 'the_token' }, @@ -2086,7 +2089,7 @@ describe('facebook limited auth adapter', () => { const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' }, }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken.header); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); const fakeGetSigningKeyAsyncFunction = () => { return { @@ -2108,7 +2111,7 @@ describe('facebook limited auth adapter', () => { const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' }, }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', @@ -2150,7 +2153,7 @@ describe('facebook limited auth adapter', () => { const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' }, }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', @@ -2177,7 +2180,7 @@ describe('facebook limited auth adapter', () => { const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' }, }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', @@ -2204,7 +2207,7 @@ describe('facebook limited auth adapter', () => { const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' }, }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', @@ -2229,7 +2232,7 @@ describe('facebook limited auth adapter', () => { const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' }, }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', @@ -2262,7 +2265,7 @@ describe('facebook limited auth adapter', () => { const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' }, }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', @@ -2296,7 +2299,7 @@ describe('facebook limited auth adapter', () => { const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' }, }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', @@ -2382,7 +2385,7 @@ describe('facebook limited auth adapter', () => { const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' }, }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); const fakeGetSigningKeyAsyncFunction = () => { return { kid: '123', diff --git a/spec/index.spec.js b/spec/index.spec.js index 5747d525df..64c4b54db7 100644 --- a/spec/index.spec.js +++ b/spec/index.spec.js @@ -587,6 +587,7 @@ describe('server', () => { it('should not fail when Google signin is introduced without the optional clientId', done => { const jwt = require('jsonwebtoken'); + const authUtils = require('../lib/Adapters/Auth/utils'); reconfigureServer({ auth: { google: {} }, @@ -599,7 +600,7 @@ describe('server', () => { sub: 'the_user_id', }; const fakeDecodedToken = { header: { kid: '123', alg: 'RS256' } }; - spyOn(jwt, 'decode').and.callFake(() => fakeDecodedToken); + spyOn(authUtils, 'getHeaderFromToken').and.callFake(() => fakeDecodedToken); spyOn(jwt, 'verify').and.callFake(() => fakeClaim); const user = new Parse.User(); user diff --git a/src/Adapters/Auth/apple.js b/src/Adapters/Auth/apple.js index 18989a4529..15b28ed203 100644 --- a/src/Adapters/Auth/apple.js +++ b/src/Adapters/Auth/apple.js @@ -5,6 +5,7 @@ const Parse = require('parse/node').Parse; const jwksClient = require('jwks-rsa'); const util = require('util'); const jwt = require('jsonwebtoken'); +const authUtils = require('./utils'); const TOKEN_ISSUER = 'https://appleid.apple.com'; @@ -30,21 +31,12 @@ const getAppleKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => { return key; }; -const getHeaderFromToken = token => { - const decodedToken = jwt.decode(token, { complete: true }); - if (!decodedToken) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`); - } - - return decodedToken.header; -}; - const verifyIdToken = async ({ token, id }, { clientId, cacheMaxEntries, cacheMaxAge }) => { if (!token) { throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`); } - const { kid: keyId, alg: algorithm } = getHeaderFromToken(token); + const { kid: keyId, alg: algorithm } = authUtils.getHeaderFromToken(token); const ONE_HOUR_IN_MS = 3600000; let jwtClaims; diff --git a/src/Adapters/Auth/facebook.js b/src/Adapters/Auth/facebook.js index e937bb1bb5..737657c8bd 100644 --- a/src/Adapters/Auth/facebook.js +++ b/src/Adapters/Auth/facebook.js @@ -5,6 +5,7 @@ const jwksClient = require('jwks-rsa'); const util = require('util'); const jwt = require('jsonwebtoken'); const httpsRequest = require('./httpsRequest'); +const authUtils = require('./utils'); const TOKEN_ISSUER = 'https://facebook.com'; @@ -73,21 +74,12 @@ const getFacebookKeyByKeyId = async (keyId, cacheMaxEntries, cacheMaxAge) => { return key; }; -const getHeaderFromToken = token => { - const decodedToken = jwt.decode(token, { complete: true }); - if (!decodedToken) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'provided token does not decode as JWT'); - } - - return decodedToken.header; -}; - const verifyIdToken = async ({ token, id }, { clientId, cacheMaxEntries, cacheMaxAge }) => { if (!token) { throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'id token is invalid for this user.'); } - const { kid: keyId, alg: algorithm } = getHeaderFromToken(token); + const { kid: keyId, alg: algorithm } = authUtils.getHeaderFromToken(token); const ONE_HOUR_IN_MS = 3600000; let jwtClaims; diff --git a/src/Adapters/Auth/google.js b/src/Adapters/Auth/google.js index 8691cf9cae..755eb3c673 100644 --- a/src/Adapters/Auth/google.js +++ b/src/Adapters/Auth/google.js @@ -5,6 +5,7 @@ var Parse = require('parse/node').Parse; const https = require('https'); const jwt = require('jsonwebtoken'); +const authUtils = require('./utils'); const TOKEN_ISSUER = 'accounts.google.com'; const HTTPS_TOKEN_ISSUER = 'https://accounts.google.com'; @@ -51,22 +52,12 @@ function getGoogleKeyByKeyId(keyId) { }); } -function getHeaderFromToken(token) { - const decodedToken = jwt.decode(token, { complete: true }); - - if (!decodedToken) { - throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`); - } - - return decodedToken.header; -} - async function verifyIdToken({ id_token: token, id }, { clientId }) { if (!token) { throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `id token is invalid for this user.`); } - const { kid: keyId, alg: algorithm } = getHeaderFromToken(token); + const { kid: keyId, alg: algorithm } = authUtils.getHeaderFromToken(token); let jwtClaims; const googleKey = await getGoogleKeyByKeyId(keyId); diff --git a/src/Adapters/Auth/utils.js b/src/Adapters/Auth/utils.js new file mode 100644 index 0000000000..c50adaba79 --- /dev/null +++ b/src/Adapters/Auth/utils.js @@ -0,0 +1,13 @@ +const jwt = require('jsonwebtoken'); +const Parse = require('parse/node').Parse; +const getHeaderFromToken = token => { + const decodedToken = jwt.decode(token, { complete: true }); + if (!decodedToken) { + throw new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, `provided token does not decode as JWT`); + } + + return decodedToken.header; +}; +module.exports = { + getHeaderFromToken, +}; From e76123b48249bc216651e41c2075331d3b30c75f Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Tue, 7 Feb 2023 11:46:57 +0000 Subject: [PATCH 06/14] chore(release): 6.0.0-alpha.32 [skip ci] # [6.0.0-alpha.32](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.31...6.0.0-alpha.32) (2023-02-07) ### Bug Fixes * Security upgrade jsonwebtoken to 9.0.0 ([#8420](https://github.com/parse-community/parse-server/issues/8420)) ([f5bfe45](https://github.com/parse-community/parse-server/commit/f5bfe4571e82b2b7440d41f3cff0d49937398164)) --- changelogs/CHANGELOG_alpha.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/changelogs/CHANGELOG_alpha.md b/changelogs/CHANGELOG_alpha.md index 97547c8efa..15f407c072 100644 --- a/changelogs/CHANGELOG_alpha.md +++ b/changelogs/CHANGELOG_alpha.md @@ -1,3 +1,10 @@ +# [6.0.0-alpha.32](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.31...6.0.0-alpha.32) (2023-02-07) + + +### Bug Fixes + +* Security upgrade jsonwebtoken to 9.0.0 ([#8420](https://github.com/parse-community/parse-server/issues/8420)) ([f5bfe45](https://github.com/parse-community/parse-server/commit/f5bfe4571e82b2b7440d41f3cff0d49937398164)) + # [6.0.0-alpha.31](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.30...6.0.0-alpha.31) (2023-01-31) diff --git a/package-lock.json b/package-lock.json index 09fb4736c7..b0207bda87 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "parse-server", - "version": "6.0.0-alpha.31", + "version": "6.0.0-alpha.32", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "parse-server", - "version": "6.0.0-alpha.31", + "version": "6.0.0-alpha.32", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 947a197bb5..8caf847983 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "parse-server", - "version": "6.0.0-alpha.31", + "version": "6.0.0-alpha.32", "description": "An express module providing a Parse-compatible API server", "main": "lib/index.js", "repository": { From 992b3c79f521a27caf47574a62765d219d3db490 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 Feb 2023 19:32:46 +0100 Subject: [PATCH 07/14] refactor: Bump cacheable-request and all-node-versions (#8430) --- package-lock.json | 1426 ++++++++++++++------------------------------- package.json | 2 +- 2 files changed, 451 insertions(+), 977 deletions(-) diff --git a/package-lock.json b/package-lock.json index b0207bda87..9fa2535b97 100644 --- a/package-lock.json +++ b/package-lock.json @@ -72,7 +72,7 @@ "@semantic-release/github": "7.2.3", "@semantic-release/npm": "7.1.3", "@semantic-release/release-notes-generator": "9.0.3", - "all-node-versions": "8.0.0", + "all-node-versions": "11.3.0", "apollo-upload-client": "17.0.0", "bcrypt-nodejs": "0.0.3", "cross-env": "7.0.2", @@ -2245,88 +2245,6 @@ "node": ">=8" } }, - "node_modules/@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/@jest/types/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@jest/types/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@jest/types/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/@jest/types/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/types/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, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", @@ -3303,27 +3221,27 @@ } }, "node_modules/@sindresorhus/is": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", - "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", + "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", "dev": true, "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sindresorhus/is?sponsor=1" } }, "node_modules/@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", "dev": true, "dependencies": { - "defer-to-connect": "^2.0.0" + "defer-to-connect": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=14.16" } }, "node_modules/@tootallnate/once": { @@ -3344,18 +3262,6 @@ "@types/node": "*" } }, - "node_modules/@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dev": true, - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, "node_modules/@types/connect": { "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", @@ -3391,31 +3297,6 @@ "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", "dev": true }, - "node_modules/@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*" - } - }, - "node_modules/@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -3430,15 +3311,6 @@ "@types/node": "*" } }, - "node_modules/@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/mime": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", @@ -3477,15 +3349,6 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, - "node_modules/@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", @@ -3515,21 +3378,6 @@ "@types/webidl-conversions": "*" } }, - "node_modules/@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true - }, "node_modules/@typescript-eslint/types": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", @@ -3711,39 +3559,58 @@ } }, "node_modules/all-node-versions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/all-node-versions/-/all-node-versions-8.0.0.tgz", - "integrity": "sha512-cF8ibgj23U7ai4qjSFzpeccwDXUlPFMzKe0Z6qf6gChR+9S0JMyzYz6oYz4n0nHi/FLH9BJIefsONsMH/WDM2w==", + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/all-node-versions/-/all-node-versions-11.3.0.tgz", + "integrity": "sha512-psMkc5s3qpr+QMfires9bC4azRYciPWql1wqZKMsYRh1731qefQDH2X4+O19xSBX6u0Ra/8Y5diG6y/fEmqKsw==", "dev": true, "dependencies": { - "fetch-node-website": "^5.0.3", - "filter-obj": "^2.0.1", - "get-stream": "^5.1.0", - "global-cache-dir": "^2.0.0", - "jest-validate": "^25.3.0", - "path-exists": "^4.0.0", - "semver": "^7.3.2", - "write-file-atomic": "^3.0.3" + "fetch-node-website": "^7.3.0", + "filter-obj": "^5.1.0", + "get-stream": "^6.0.0", + "global-cache-dir": "^4.3.1", + "is-plain-obj": "^4.1.0", + "path-exists": "^5.0.0", + "semver": "^7.3.7", + "write-file-atomic": "^4.0.1" }, "engines": { - "node": ">=10.17.0" + "node": ">=14.18.0" } }, - "node_modules/all-node-versions/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "node_modules/all-node-versions/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/all-node-versions/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/all-node-versions/node_modules/write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, "node_modules/ampersand-events": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/ampersand-events/-/ampersand-events-2.0.2.tgz", @@ -4713,46 +4580,39 @@ } }, "node_modules/cacheable-lookup": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-2.0.1.tgz", - "integrity": "sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", "dev": true, - "dependencies": { - "@types/keyv": "^3.1.1", - "keyv": "^4.0.0" - }, "engines": { - "node": ">=10" + "node": ">=14.16" } }, "node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "version": "10.2.7", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.7.tgz", + "integrity": "sha512-I4SA6mKgDxcxVbSt/UmIkb9Ny8qSkg6ReBHtAAXnZHk7KOSx5g3DTiAOaYzcHCs6oOdHn+bip9T48E6tMvK9hw==", "dev": true, "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" + "@types/http-cache-semantics": "^4.0.1", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.2", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=14.16" } }, - "node_modules/cacheable-request/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "node_modules/cacheable-request/node_modules/normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, "engines": { - "node": ">=8" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -5106,27 +4966,6 @@ "node": ">=0.8" } }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/clone-response/node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, "node_modules/clui": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/clui/-/clui-0.3.6.tgz", @@ -5206,6 +5045,43 @@ "node": ">=0.1.90" } }, + "node_modules/colors-option": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/colors-option/-/colors-option-4.5.0.tgz", + "integrity": "sha512-Soe5lerRg3erMRgYC0EC696/8dMCGpBzcQchFfi55Yrkja8F+P7cUt0LVTIg7u5ob5BexLZ/F1kO+ejmv+nq8w==", + "dev": true, + "dependencies": { + "chalk": "^5.0.1", + "is-plain-obj": "^4.1.0" + }, + "engines": { + "node": ">=14.18.0" + } + }, + "node_modules/colors-option/node_modules/chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "dev": true, + "engines": { + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/colors-option/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/colorspace": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", @@ -5708,15 +5584,30 @@ } }, "node_modules/decompress-response": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz", - "integrity": "sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, "dependencies": { - "mimic-response": "^2.0.0" + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, "engines": { "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/decompress-tar": { @@ -7574,90 +7465,71 @@ } }, "node_modules/fetch-node-website": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/fetch-node-website/-/fetch-node-website-5.0.3.tgz", - "integrity": "sha512-O86T46FUWSOq4AWON39oaT8H90QFKAbmjfOVBhgaS87AFfeW00txz73KTv7QopPWtHBbGdI1S8cIT1VK1OQYLg==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/fetch-node-website/-/fetch-node-website-7.3.0.tgz", + "integrity": "sha512-/wayUHbdVUWrD72aqRNNrr6+MHnCkumZgNugN0RfiWJpbNJUdAkMk4Z18MGayGZVVqYXR1RWrV+bIFEt5HuBZg==", "dev": true, "dependencies": { - "chalk": "^4.0.0", - "cli-progress": "^3.7.0", - "figures": "^3.2.0", - "filter-obj": "^2.0.1", - "got": "^10.7.0", - "jest-validate": "^25.3.0" + "cli-progress": "^3.11.2", + "colors-option": "^4.4.0", + "figures": "^5.0.0", + "got": "^12.3.1", + "is-plain-obj": "^4.1.0" }, "engines": { - "node": ">=10.17.0" + "node": ">=14.18.0" } }, - "node_modules/fetch-node-website/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "node_modules/fetch-node-website/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, "engines": { - "node": ">=8" + "node": ">=12" }, "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fetch-node-website/node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "node_modules/fetch-node-website/node_modules/figures": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", + "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "escape-string-regexp": "^5.0.0", + "is-unicode-supported": "^1.2.0" }, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fetch-node-website/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "node_modules/fetch-node-website/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, "engines": { - "node": ">=7.0.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/fetch-node-website/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/fetch-node-website/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "node_modules/fetch-node-website/node_modules/is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", "dev": true, "engines": { - "node": ">=8" - } - }, - "node_modules/fetch-node-website/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, - "dependencies": { - "has-flag": "^4.0.0" + "node": ">=12" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/figures": { @@ -7783,12 +7655,15 @@ } }, "node_modules/filter-obj": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", - "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-5.1.0.tgz", + "integrity": "sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==", "dev": true, "engines": { - "node": ">=8" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/finalhandler": { @@ -8491,16 +8366,25 @@ } }, "node_modules/global-cache-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-cache-dir/-/global-cache-dir-2.0.0.tgz", - "integrity": "sha512-30pvU3e8muclEhc9tt+jRMaywOS3QfNdURflJ5Zv0bohjhcVQpBe5bwRHghGSJORLOKW81/n+3iJvHRHs+/S1Q==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global-cache-dir/-/global-cache-dir-4.4.0.tgz", + "integrity": "sha512-bk0gI6IbbphRjAaCJJn5H+T/CcEck5B3a5KBO2BXSDzjFSV+API17w8GA7YPJ6IXJiasW8M0VsEIig1PCHdfOQ==", "dev": true, "dependencies": { "cachedir": "^2.3.0", - "path-exists": "^4.0.0" + "path-exists": "^5.0.0" }, "engines": { - "node": ">=10.17.0" + "node": ">=14.18.0" + } + }, + "node_modules/global-cache-dir/node_modules/path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } }, "node_modules/globals": { @@ -8556,47 +8440,37 @@ } }, "node_modules/got": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/got/-/got-10.7.0.tgz", - "integrity": "sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==", + "version": "12.5.3", + "resolved": "https://registry.npmjs.org/got/-/got-12.5.3.tgz", + "integrity": "sha512-8wKnb9MGU8IPGRIo+/ukTy9XLJBwDiCpIf5TVzQ9Cpol50eMTpBq2GAuDsuDIz7hTYmZgMgC1e9ydr6kSDWs3w==", "dev": true, "dependencies": { - "@sindresorhus/is": "^2.0.0", - "@szmarczak/http-timer": "^4.0.0", - "@types/cacheable-request": "^6.0.1", - "cacheable-lookup": "^2.0.0", - "cacheable-request": "^7.0.1", - "decompress-response": "^5.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^5.0.0", - "lowercase-keys": "^2.0.0", - "mimic-response": "^2.1.0", - "p-cancelable": "^2.0.0", - "p-event": "^4.0.0", - "responselike": "^2.0.0", - "to-readable-stream": "^2.0.0", - "type-fest": "^0.10.0" + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.1", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">=14.16" }, "funding": { "url": "https://github.com/sindresorhus/got?sponsor=1" } }, - "node_modules/got/node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "node_modules/got/node_modules/form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 14.17" } }, "node_modules/graceful-fs": { @@ -8969,6 +8843,31 @@ "npm": ">=1.3.7" } }, + "node_modules/http2-wrapper": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz", + "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/http2-wrapper/node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -9893,99 +9792,6 @@ "node": ">= 0.6.0" } }, - "node_modules/jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-validate": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", - "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", - "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "jest-get-type": "^25.2.6", - "leven": "^3.1.0", - "pretty-format": "^25.5.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/jest-validate/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/jest-validate/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/jest-validate/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "node_modules/jest-validate/node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/jest-validate/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, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/jose": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.6.tgz", @@ -11080,12 +10886,15 @@ } }, "node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", "dev": true, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/lru-cache": { @@ -11563,12 +11372,12 @@ } }, "node_modules/mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", "dev": true, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -15927,12 +15736,12 @@ } }, "node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", "dev": true, "engines": { - "node": ">=8" + "node": ">=12.20" } }, "node_modules/p-each-series": { @@ -15947,21 +15756,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-event": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", - "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "dev": true, - "dependencies": { - "p-timeout": "^3.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/p-filter": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", @@ -16066,18 +15860,6 @@ "node": ">=8" } }, - "node_modules/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -16803,54 +16585,6 @@ "node": ">=10.13.0" } }, - "node_modules/pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "dependencies": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "engines": { - "node": ">= 8.3" - } - }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/pretty-format/node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/pretty-format/node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, "node_modules/pretty-ms": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", @@ -17778,6 +17512,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, "node_modules/resolve-dependency-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-dependency-path/-/resolve-dependency-path-2.0.0.tgz", @@ -17804,12 +17544,15 @@ "optional": true }, "node_modules/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", "dev": true, "dependencies": { - "lowercase-keys": "^2.0.0" + "lowercase-keys": "^3.0.0" + }, + "engines": { + "node": ">=14.16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -19485,15 +19228,6 @@ "node": ">=0.10.0" } }, - "node_modules/to-readable-stream": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz", - "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", @@ -19831,18 +19565,6 @@ "node": ">=4" } }, - "node_modules/type-fest": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", - "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==", - "dev": true, - "engines": { - "node": ">=8" - }, - "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", @@ -22266,69 +21988,6 @@ "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, - "@jest/types": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-25.5.0.tgz", - "integrity": "sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^1.1.1", - "@types/yargs": "^15.0.0", - "chalk": "^3.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "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, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "@jridgewell/gen-mapping": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", @@ -23051,18 +22710,18 @@ } }, "@sindresorhus/is": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-2.1.1.tgz", - "integrity": "sha512-/aPsuoj/1Dw/kzhkgz+ES6TxG0zfTMGLwuK2ZG00k/iJzYHTLCE8mVU8EPqEOp/lmxPoq1C1C9RYToRKb2KEfg==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-5.3.0.tgz", + "integrity": "sha512-CX6t4SYQ37lzxicAqsBtxA3OseeoVrh9cSJ5PFYam0GksYlupRfy1A+Q4aYD3zvcfECLc0zO2u+ZnR2UYKvCrw==", "dev": true }, "@szmarczak/http-timer": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", - "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-5.0.1.tgz", + "integrity": "sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==", "dev": true, "requires": { - "defer-to-connect": "^2.0.0" + "defer-to-connect": "^2.0.1" } }, "@tootallnate/once": { @@ -23080,18 +22739,6 @@ "@types/node": "*" } }, - "@types/cacheable-request": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", - "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", - "dev": true, - "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "^3.1.4", - "@types/node": "*", - "@types/responselike": "^1.0.0" - } - }, "@types/connect": { "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", @@ -23127,31 +22774,6 @@ "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", "dev": true }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-1.1.2.tgz", - "integrity": "sha512-P/W9yOX/3oPZSpaYOCQzGqgCQRXn0FFO/V8bWrCQs+wLmvVVxk6CRBXALEvNs9OHIatlnlFokfhuDo2ug01ciw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*", - "@types/istanbul-lib-report": "*" - } - }, "@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -23166,15 +22788,6 @@ "@types/node": "*" } }, - "@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/mime": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/mime/-/mime-3.0.1.tgz", @@ -23213,15 +22826,6 @@ "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==" }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", @@ -23251,21 +22855,6 @@ "@types/webidl-conversions": "*" } }, - "@types/yargs": { - "version": "15.0.14", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.14.tgz", - "integrity": "sha512-yEJzHoxf6SyQGhBhIYGXQDSCkJjB6HohDShto7m8vaKg9Yp0Yn8+71J9eakh2bnPg6BfsH9PRMhiRTZnd4eXGQ==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true - }, "@typescript-eslint/types": { "version": "4.33.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", @@ -23388,28 +22977,41 @@ } }, "all-node-versions": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/all-node-versions/-/all-node-versions-8.0.0.tgz", - "integrity": "sha512-cF8ibgj23U7ai4qjSFzpeccwDXUlPFMzKe0Z6qf6gChR+9S0JMyzYz6oYz4n0nHi/FLH9BJIefsONsMH/WDM2w==", + "version": "11.3.0", + "resolved": "https://registry.npmjs.org/all-node-versions/-/all-node-versions-11.3.0.tgz", + "integrity": "sha512-psMkc5s3qpr+QMfires9bC4azRYciPWql1wqZKMsYRh1731qefQDH2X4+O19xSBX6u0Ra/8Y5diG6y/fEmqKsw==", "dev": true, "requires": { - "fetch-node-website": "^5.0.3", - "filter-obj": "^2.0.1", - "get-stream": "^5.1.0", - "global-cache-dir": "^2.0.0", - "jest-validate": "^25.3.0", - "path-exists": "^4.0.0", - "semver": "^7.3.2", - "write-file-atomic": "^3.0.3" + "fetch-node-website": "^7.3.0", + "filter-obj": "^5.1.0", + "get-stream": "^6.0.0", + "global-cache-dir": "^4.3.1", + "is-plain-obj": "^4.1.0", + "path-exists": "^5.0.0", + "semver": "^7.3.7", + "write-file-atomic": "^4.0.1" }, "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true + }, + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true + }, + "write-file-atomic": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", + "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, "requires": { - "pump": "^3.0.0" + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" } } } @@ -24186,38 +23788,31 @@ } }, "cacheable-lookup": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-2.0.1.tgz", - "integrity": "sha512-EMMbsiOTcdngM/K6gV/OxF2x0t07+vMOWxZNSCRQMjO2MY2nhZQ6OYhOOpyQrbhqsgtvKGI7hcq6xjnA92USjg==", - "dev": true, - "requires": { - "@types/keyv": "^3.1.1", - "keyv": "^4.0.0" - } + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-7.0.0.tgz", + "integrity": "sha512-+qJyx4xiKra8mZrcwhjMRMUhD5NR1R8esPkzIYxX96JiecFoxAXFuz/GpR3+ev4PE1WamHip78wV0vcmPQtp8w==", + "dev": true }, "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "version": "10.2.7", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-10.2.7.tgz", + "integrity": "sha512-I4SA6mKgDxcxVbSt/UmIkb9Ny8qSkg6ReBHtAAXnZHk7KOSx5g3DTiAOaYzcHCs6oOdHn+bip9T48E6tMvK9hw==", "dev": true, "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" + "@types/http-cache-semantics": "^4.0.1", + "get-stream": "^6.0.1", + "http-cache-semantics": "^4.1.1", + "keyv": "^4.5.2", + "mimic-response": "^4.0.0", + "normalize-url": "^8.0.0", + "responselike": "^3.0.0" }, "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } + "normalize-url": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-8.0.0.tgz", + "integrity": "sha512-uVFpKhj5MheNBJRTiMZ9pE/7hD1QTeEvugSJW/OmLzAp78PB5O6adfMNTvmfKhXBkvCzC+rqifWcVYpGFwTjnw==", + "dev": true } } }, @@ -24481,23 +24076,6 @@ "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==", "dev": true }, - "clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - }, - "dependencies": { - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": true - } - } - }, "clui": { "version": "0.3.6", "resolved": "https://registry.npmjs.org/clui/-/clui-0.3.6.tgz", @@ -24565,6 +24143,30 @@ "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", "dev": true }, + "colors-option": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/colors-option/-/colors-option-4.5.0.tgz", + "integrity": "sha512-Soe5lerRg3erMRgYC0EC696/8dMCGpBzcQchFfi55Yrkja8F+P7cUt0LVTIg7u5ob5BexLZ/F1kO+ejmv+nq8w==", + "dev": true, + "requires": { + "chalk": "^5.0.1", + "is-plain-obj": "^4.1.0" + }, + "dependencies": { + "chalk": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.2.0.tgz", + "integrity": "sha512-ree3Gqw/nazQAPuJJEy+avdl7QfZMcUvmHIKgEZkGL+xOBzRvup5Hxo6LHuMceSxOabuJLJm5Yp/92R9eMmMvA==", + "dev": true + }, + "is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true + } + } + }, "colorspace": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/colorspace/-/colorspace-1.1.4.tgz", @@ -24980,12 +24582,20 @@ } }, "decompress-response": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-5.0.0.tgz", - "integrity": "sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "dev": true, "requires": { - "mimic-response": "^2.0.0" + "mimic-response": "^3.1.0" + }, + "dependencies": { + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true + } } }, "decompress-tar": { @@ -26449,67 +26059,45 @@ } }, "fetch-node-website": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/fetch-node-website/-/fetch-node-website-5.0.3.tgz", - "integrity": "sha512-O86T46FUWSOq4AWON39oaT8H90QFKAbmjfOVBhgaS87AFfeW00txz73KTv7QopPWtHBbGdI1S8cIT1VK1OQYLg==", + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/fetch-node-website/-/fetch-node-website-7.3.0.tgz", + "integrity": "sha512-/wayUHbdVUWrD72aqRNNrr6+MHnCkumZgNugN0RfiWJpbNJUdAkMk4Z18MGayGZVVqYXR1RWrV+bIFEt5HuBZg==", "dev": true, "requires": { - "chalk": "^4.0.0", - "cli-progress": "^3.7.0", - "figures": "^3.2.0", - "filter-obj": "^2.0.1", - "got": "^10.7.0", - "jest-validate": "^25.3.0" + "cli-progress": "^3.11.2", + "colors-option": "^4.4.0", + "figures": "^5.0.0", + "got": "^12.3.1", + "is-plain-obj": "^4.1.0" }, "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } + "escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "figures": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-5.0.0.tgz", + "integrity": "sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==", "dev": true, "requires": { - "color-name": "~1.1.4" + "escape-string-regexp": "^5.0.0", + "is-unicode-supported": "^1.2.0" } }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "dev": true }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "is-unicode-supported": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz", + "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==", "dev": true - }, - "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, - "requires": { - "has-flag": "^4.0.0" - } } } }, @@ -26611,9 +26199,9 @@ } }, "filter-obj": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-2.0.2.tgz", - "integrity": "sha512-lO3ttPjHZRfjMcxWKb1j1eDhTFsu4meeR3lnMcnBFhk6RuLhvEiuALu2TlfL310ph4lCYYwgF/ElIjdP739tdg==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/filter-obj/-/filter-obj-5.1.0.tgz", + "integrity": "sha512-qWeTREPoT7I0bifpPUXtxkZJ1XJzxWtfoWWkdVGqa+eCr3SHW/Ocp89o8vLvbUuQnadybJpjOKu4V+RwO6sGng==", "dev": true }, "finalhandler": { @@ -27144,13 +26732,21 @@ } }, "global-cache-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-cache-dir/-/global-cache-dir-2.0.0.tgz", - "integrity": "sha512-30pvU3e8muclEhc9tt+jRMaywOS3QfNdURflJ5Zv0bohjhcVQpBe5bwRHghGSJORLOKW81/n+3iJvHRHs+/S1Q==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/global-cache-dir/-/global-cache-dir-4.4.0.tgz", + "integrity": "sha512-bk0gI6IbbphRjAaCJJn5H+T/CcEck5B3a5KBO2BXSDzjFSV+API17w8GA7YPJ6IXJiasW8M0VsEIig1PCHdfOQ==", "dev": true, "requires": { "cachedir": "^2.3.0", - "path-exists": "^4.0.0" + "path-exists": "^5.0.0" + }, + "dependencies": { + "path-exists": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz", + "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==", + "dev": true + } } }, "globals": { @@ -27190,36 +26786,29 @@ } }, "got": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/got/-/got-10.7.0.tgz", - "integrity": "sha512-aWTDeNw9g+XqEZNcTjMMZSy7B7yE9toWOFYip7ofFTLleJhvZwUxxTxkTpKvF+p1SAA4VHmuEy7PiHTHyq8tJg==", - "dev": true, - "requires": { - "@sindresorhus/is": "^2.0.0", - "@szmarczak/http-timer": "^4.0.0", - "@types/cacheable-request": "^6.0.1", - "cacheable-lookup": "^2.0.0", - "cacheable-request": "^7.0.1", - "decompress-response": "^5.0.0", - "duplexer3": "^0.1.4", - "get-stream": "^5.0.0", - "lowercase-keys": "^2.0.0", - "mimic-response": "^2.1.0", - "p-cancelable": "^2.0.0", - "p-event": "^4.0.0", - "responselike": "^2.0.0", - "to-readable-stream": "^2.0.0", - "type-fest": "^0.10.0" - }, - "dependencies": { - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } + "version": "12.5.3", + "resolved": "https://registry.npmjs.org/got/-/got-12.5.3.tgz", + "integrity": "sha512-8wKnb9MGU8IPGRIo+/ukTy9XLJBwDiCpIf5TVzQ9Cpol50eMTpBq2GAuDsuDIz7hTYmZgMgC1e9ydr6kSDWs3w==", + "dev": true, + "requires": { + "@sindresorhus/is": "^5.2.0", + "@szmarczak/http-timer": "^5.0.1", + "cacheable-lookup": "^7.0.0", + "cacheable-request": "^10.2.1", + "decompress-response": "^6.0.0", + "form-data-encoder": "^2.1.2", + "get-stream": "^6.0.1", + "http2-wrapper": "^2.1.10", + "lowercase-keys": "^3.0.0", + "p-cancelable": "^3.0.0", + "responselike": "^3.0.0" + }, + "dependencies": { + "form-data-encoder": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-2.1.4.tgz", + "integrity": "sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==", + "dev": true } } }, @@ -27507,6 +27096,24 @@ "sshpk": "^1.7.0" } }, + "http2-wrapper": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-2.2.0.tgz", + "integrity": "sha512-kZB0wxMo0sh1PehyjJUWRFEd99KC5TLjZ2cULC4f9iqJBAmKQQXEICjxl5iPJRwP40dpeHFqqhm7tYCvODpqpQ==", + "dev": true, + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.2.0" + }, + "dependencies": { + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true + } + } + }, "https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -28202,77 +27809,6 @@ "integrity": "sha512-qjdpeo2yKlYTH7nFdK0vbZWuTCesk4o63v5iVOlhMQPfuIZQfW/HI35SjfhA+4qpg36rnFSvUK5b1m+ckIblQQ==", "dev": true }, - "jest-get-type": { - "version": "25.2.6", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-25.2.6.tgz", - "integrity": "sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig==", - "dev": true - }, - "jest-validate": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-25.5.0.tgz", - "integrity": "sha512-okUFKqhZIpo3jDdtUXUZ2LxGUZJIlfdYBvZb1aczzxrlyMlqdnnws9MOxezoLGhSaFc2XYaHNReNQfj5zPIWyQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "camelcase": "^5.3.1", - "chalk": "^3.0.0", - "jest-get-type": "^25.2.6", - "leven": "^3.1.0", - "pretty-format": "^25.5.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "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, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "jose": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/jose/-/jose-2.0.6.tgz", @@ -29158,9 +28694,9 @@ } }, "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-3.0.0.tgz", + "integrity": "sha512-ozCC6gdQ+glXOQsveKD0YsDy8DSQFjDTz4zyzEHNV5+JP5D62LmfDZ6o1cycFx9ouG940M5dE8C8CTewdj2YWQ==", "dev": true }, "lru-cache": { @@ -29531,9 +29067,9 @@ "dev": true }, "mimic-response": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-2.1.0.tgz", - "integrity": "sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-4.0.0.tgz", + "integrity": "sha512-e5ISH9xMYU0DzrT+jl8q2ze9D6eWBto+I8CNpe+VI+K2J/F/k3PdkdTdz4wvGVH4NTpo+NRYTVIuMQEMMcsLqg==", "dev": true }, "min-indent": { @@ -32758,9 +32294,9 @@ } }, "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-3.0.0.tgz", + "integrity": "sha512-mlVgR3PGuzlo0MmTdk4cXqXWlwQDLnONTAg6sm62XkMJEiRxN3GL3SffkYvqwonbkJBcrI7Uvv5Zh9yjvn2iUw==", "dev": true }, "p-each-series": { @@ -32769,15 +32305,6 @@ "integrity": "sha512-ycIL2+1V32th+8scbpTvyHNaHe02z0sjgh91XXjAk+ZeXoPN4Z46DVUnzdso0aX4KckKw0FNNFHdjZ2UsZvxiA==", "dev": true }, - "p-event": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-4.2.0.tgz", - "integrity": "sha512-KXatOjCRXXkSePPb1Nbi0p0m+gQAwdlbhi4wQKJPI1HsMQS9g+Sqp2o+QHziPr7eYJyOZet836KoHEVM1mwOrQ==", - "dev": true, - "requires": { - "p-timeout": "^3.1.0" - } - }, "p-filter": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-filter/-/p-filter-2.1.0.tgz", @@ -32848,15 +32375,6 @@ "retry": "^0.13.1" } }, - "p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dev": true, - "requires": { - "p-finally": "^1.0.0" - } - }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -33395,44 +32913,6 @@ "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", "dev": true }, - "pretty-format": { - "version": "25.5.0", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-25.5.0.tgz", - "integrity": "sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ==", - "dev": true, - "requires": { - "@jest/types": "^25.5.0", - "ansi-regex": "^5.0.0", - "ansi-styles": "^4.0.0", - "react-is": "^16.12.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - } - } - }, "pretty-ms": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-7.0.1.tgz", @@ -34168,6 +33648,12 @@ "supports-preserve-symlinks-flag": "^1.0.0" } }, + "resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, "resolve-dependency-path": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/resolve-dependency-path/-/resolve-dependency-path-2.0.0.tgz", @@ -34187,12 +33673,12 @@ "optional": true }, "responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-3.0.0.tgz", + "integrity": "sha512-40yHxbNcl2+rzXvZuVkrYohathsSJlMTXKryG5y8uciHv1+xDLHQpgjG64JUO9nrEq2jGLH6IZ8BcZyw3wrweg==", "dev": true, "requires": { - "lowercase-keys": "^2.0.0" + "lowercase-keys": "^3.0.0" } }, "restore-cursor": { @@ -35504,12 +34990,6 @@ "kind-of": "^3.0.2" } }, - "to-readable-stream": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-2.1.0.tgz", - "integrity": "sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==", - "dev": true - }, "to-regex": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", @@ -35774,12 +35254,6 @@ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==" }, - "type-fest": { - "version": "0.10.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.10.0.tgz", - "integrity": "sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==", - "dev": true - }, "type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", diff --git a/package.json b/package.json index 8caf847983..9d69e2ebfa 100644 --- a/package.json +++ b/package.json @@ -78,7 +78,7 @@ "@semantic-release/github": "7.2.3", "@semantic-release/npm": "7.1.3", "@semantic-release/release-notes-generator": "9.0.3", - "all-node-versions": "8.0.0", + "all-node-versions": "11.3.0", "apollo-upload-client": "17.0.0", "bcrypt-nodejs": "0.0.3", "cross-env": "7.0.2", From a49e323d5ae640bff1c6603ec37fdaddb9328dd1 Mon Sep 17 00:00:00 2001 From: Daniel Date: Fri, 17 Feb 2023 23:24:33 +1100 Subject: [PATCH 08/14] feat: Deprecate LiveQuery `fields` option in favor of `keys` for semantic consistency (#8388) --- DEPRECATIONS.md | 1 + spec/ParseLiveQueryServer.spec.js | 68 ++++++++++++++++++++++++--- src/LiveQuery/Client.js | 8 ++-- src/LiveQuery/ParseLiveQueryServer.js | 15 ++++-- src/LiveQuery/RequestSchema.js | 32 +++++++++++++ 5 files changed, 110 insertions(+), 14 deletions(-) diff --git a/DEPRECATIONS.md b/DEPRECATIONS.md index a647782210..56359c937e 100644 --- a/DEPRECATIONS.md +++ b/DEPRECATIONS.md @@ -12,6 +12,7 @@ The following is a list of deprecations, according to the [Deprecation Policy](h | DEPPS6 | Auth providers disabled by default | [#7953](https://github.com/parse-community/parse-server/pull/7953) | 5.3.0 (2022) | 7.0.0 (2024) | deprecated | - | | DEPPS7 | Remove file trigger syntax `Parse.Cloud.beforeSaveFile((request) => {})` | [#7966](https://github.com/parse-community/parse-server/pull/7966) | 5.3.0 (2022) | 7.0.0 (2024) | deprecated | - | | DEPPS8 | Login with expired 3rd party authentication token defaults to `false` | [#7079](https://github.com/parse-community/parse-server/pull/7079) | 5.3.0 (2022) | 7.0.0 (2024) | deprecated | - | +| DEPPS9 | Rename LiveQuery `fields` option to `keys` | [#8389](https://github.com/parse-community/parse-server/issues/8389) | 6.0.0 (2023) | 7.0.0 (2024) | deprecated | - | [i_deprecation]: ## "The version and date of the deprecation." [i_removal]: ## "The version and date of the planned removal." diff --git a/spec/ParseLiveQueryServer.spec.js b/spec/ParseLiveQueryServer.spec.js index 47e90733a1..5b4690ae85 100644 --- a/spec/ParseLiveQueryServer.spec.js +++ b/spec/ParseLiveQueryServer.spec.js @@ -294,7 +294,7 @@ describe('ParseLiveQueryServer', function () { where: { key: 'value', }, - fields: ['test'], + keys: ['test'], }; const requestId = 2; const request = { @@ -331,7 +331,7 @@ describe('ParseLiveQueryServer', function () { where: { key: 'value', }, - fields: ['test'], + keys: ['test'], }; const requestId = 2; const request = { @@ -378,7 +378,7 @@ describe('ParseLiveQueryServer', function () { where: { key: 'value', }, - fields: ['test'], + keys: ['test'], }; await addMockSubscription(parseLiveQueryServer, clientId, requestId, parseWebSocket, query); // Add subscription for mock client 2 @@ -390,7 +390,7 @@ describe('ParseLiveQueryServer', function () { where: { key: 'value', }, - fields: ['testAgain'], + keys: ['testAgain'], }; const requestIdAgain = 1; await addMockSubscription( @@ -1060,7 +1060,7 @@ describe('ParseLiveQueryServer', function () { where: { key: 'value', }, - fields: ['test'], + keys: ['test'], }; await addMockSubscription(parseLiveQueryServer, clientId, requestId, parseWebSocket, query); // Mock _matchesSubscription to return matching @@ -1087,6 +1087,62 @@ describe('ParseLiveQueryServer', function () { done(); }); + it('can deprecate fields', async () => { + const Deprecator = require('../lib/Deprecator/Deprecator'); + const spy = spyOn(Deprecator, 'logRuntimeDeprecation').and.callFake(() => {}); + jasmine.restoreLibrary('../lib/LiveQuery/Client', 'Client'); + const Client = require('../lib/LiveQuery/Client').Client; + const parseLiveQueryServer = new ParseLiveQueryServer({}); + // Make mock request message + const message = generateMockMessage(); + + const clientId = 1; + const parseWebSocket = { + clientId, + send: jasmine.createSpy('send'), + }; + const client = new Client(clientId, parseWebSocket); + spyOn(client, 'pushCreate').and.callThrough(); + parseLiveQueryServer.clients.set(clientId, client); + + // Add mock subscription + const requestId = 2; + const query = { + className: testClassName, + where: { + key: 'value', + }, + fields: ['test'], + }; + await addMockSubscription(parseLiveQueryServer, clientId, requestId, parseWebSocket, query); + // Mock _matchesSubscription to return matching + parseLiveQueryServer._matchesSubscription = function (parseObject) { + if (!parseObject) { + return false; + } + return true; + }; + parseLiveQueryServer._matchesACL = function () { + return Promise.resolve(true); + }; + + parseLiveQueryServer._onAfterSave(message); + + // Make sure we send create command to client + await timeout(); + + expect(client.pushCreate).toHaveBeenCalled(); + const args = parseWebSocket.send.calls.mostRecent().args; + const toSend = JSON.parse(args[0]); + expect(toSend.object).toBeDefined(); + expect(toSend.original).toBeUndefined(); + expect(spy).toHaveBeenCalledWith({ + usage: 'Subscribing using fields parameter', + solution: + `Subscribe using "keys" instead.`, + }); + }); + it('can handle create command with watch', async () => { jasmine.restoreLibrary('../lib/LiveQuery/Client', 'Client'); const Client = require('../lib/LiveQuery/Client').Client; @@ -1865,7 +1921,7 @@ describe('ParseLiveQueryServer', function () { where: { key: 'value', }, - fields: ['test'], + keys: ['test'], }; } const request = { diff --git a/src/LiveQuery/Client.js b/src/LiveQuery/Client.js index 56d1baedcd..0ce629bd4e 100644 --- a/src/LiveQuery/Client.js +++ b/src/LiveQuery/Client.js @@ -98,13 +98,13 @@ class Client { response['requestId'] = subscriptionId; } if (typeof parseObjectJSON !== 'undefined') { - let fields; + let keys; if (this.subscriptionInfos.has(subscriptionId)) { - fields = this.subscriptionInfos.get(subscriptionId).fields; + keys = this.subscriptionInfos.get(subscriptionId).keys; } - response['object'] = this._toJSONWithFields(parseObjectJSON, fields); + response['object'] = this._toJSONWithFields(parseObjectJSON, keys); if (parseOriginalObjectJSON) { - response['original'] = this._toJSONWithFields(parseOriginalObjectJSON, fields); + response['original'] = this._toJSONWithFields(parseOriginalObjectJSON, keys); } } Client.pushResponse(this.parseWebSocket, JSON.stringify(response)); diff --git a/src/LiveQuery/ParseLiveQueryServer.js b/src/LiveQuery/ParseLiveQueryServer.js index 1ecbda9372..934a556966 100644 --- a/src/LiveQuery/ParseLiveQueryServer.js +++ b/src/LiveQuery/ParseLiveQueryServer.js @@ -23,6 +23,7 @@ import LRU from 'lru-cache'; import UserRouter from '../Routers/UsersRouter'; import DatabaseController from '../Controllers/DatabaseController'; import { isDeepStrictEqual } from 'util'; +import Deprecator from '../Deprecator/Deprecator'; class ParseLiveQueryServer { clients: Map; @@ -850,9 +851,6 @@ class ParseLiveQueryServer { await runTrigger(trigger, `beforeSubscribe.${className}`, request, auth); const query = request.query.toJSON(); - if (query.keys) { - query.fields = query.keys.split(','); - } request.query = query; } @@ -901,8 +899,17 @@ class ParseLiveQueryServer { subscription: subscription, }; // Add selected fields, sessionToken and installationId for this subscription if necessary + if (request.query.keys) { + subscriptionInfo.keys = Array.isArray(request.query.keys) + ? request.query.keys + : request.query.keys.split(','); + } if (request.query.fields) { - subscriptionInfo.fields = request.query.fields; + subscriptionInfo.keys = request.query.fields; + Deprecator.logRuntimeDeprecation({ + usage: `Subscribing using fields parameter`, + solution: `Subscribe using "keys" instead.`, + }); } if (request.query.watch) { subscriptionInfo.watch = request.query.watch; diff --git a/src/LiveQuery/RequestSchema.js b/src/LiveQuery/RequestSchema.js index 14cb2f046b..3a88e9930d 100644 --- a/src/LiveQuery/RequestSchema.js +++ b/src/LiveQuery/RequestSchema.js @@ -70,6 +70,22 @@ const subscribe = { minItems: 1, uniqueItems: true, }, + keys: { + type: 'array', + items: { + type: 'string', + }, + minItems: 1, + uniqueItems: true, + }, + watch: { + type: 'array', + items: { + type: 'string', + }, + minItems: 1, + uniqueItems: true, + }, }, required: ['where', 'className'], additionalProperties: false, @@ -108,6 +124,22 @@ const update = { minItems: 1, uniqueItems: true, }, + keys: { + type: 'array', + items: { + type: 'string', + }, + minItems: 1, + uniqueItems: true, + }, + watch: { + type: 'array', + items: { + type: 'string', + }, + minItems: 1, + uniqueItems: true, + }, }, required: ['where', 'className'], additionalProperties: false, From 5477848518370292433e945d35745cd8014813d8 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 17 Feb 2023 12:25:43 +0000 Subject: [PATCH 09/14] chore(release): 6.0.0-alpha.33 [skip ci] # [6.0.0-alpha.33](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.32...6.0.0-alpha.33) (2023-02-17) ### Features * Deprecate LiveQuery `fields` option in favor of `keys` for semantic consistency ([#8388](https://github.com/parse-community/parse-server/issues/8388)) ([a49e323](https://github.com/parse-community/parse-server/commit/a49e323d5ae640bff1c6603ec37fdaddb9328dd1)) --- changelogs/CHANGELOG_alpha.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/changelogs/CHANGELOG_alpha.md b/changelogs/CHANGELOG_alpha.md index 15f407c072..74510e0a3f 100644 --- a/changelogs/CHANGELOG_alpha.md +++ b/changelogs/CHANGELOG_alpha.md @@ -1,3 +1,10 @@ +# [6.0.0-alpha.33](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.32...6.0.0-alpha.33) (2023-02-17) + + +### Features + +* Deprecate LiveQuery `fields` option in favor of `keys` for semantic consistency ([#8388](https://github.com/parse-community/parse-server/issues/8388)) ([a49e323](https://github.com/parse-community/parse-server/commit/a49e323d5ae640bff1c6603ec37fdaddb9328dd1)) + # [6.0.0-alpha.32](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.31...6.0.0-alpha.32) (2023-02-07) diff --git a/package-lock.json b/package-lock.json index 9fa2535b97..767d98cbce 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "parse-server", - "version": "6.0.0-alpha.32", + "version": "6.0.0-alpha.33", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "parse-server", - "version": "6.0.0-alpha.32", + "version": "6.0.0-alpha.33", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 9d69e2ebfa..2e5eb8590c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "parse-server", - "version": "6.0.0-alpha.32", + "version": "6.0.0-alpha.33", "description": "An express module providing a Parse-compatible API server", "main": "lib/index.js", "repository": { From e5d610e5e487ddab86409409ac3d7362aba8f59b Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 25 Feb 2023 06:30:48 +1100 Subject: [PATCH 10/14] feat: Add Parse Server option `resetPasswordSuccessOnInvalidEmail` to choose success or error response on password reset with invalid email (#7551) --- spec/ValidationAndPasswordsReset.spec.js | 39 ++++++++++++++++++++++++ src/Config.js | 7 +++++ src/Options/Definitions.js | 7 +++++ src/Options/docs.js | 1 + src/Options/index.js | 5 +++ src/Routers/UsersRouter.js | 30 +++++++++--------- 6 files changed, 73 insertions(+), 16 deletions(-) diff --git a/spec/ValidationAndPasswordsReset.spec.js b/spec/ValidationAndPasswordsReset.spec.js index a8ae169cf0..3272f07fc3 100644 --- a/spec/ValidationAndPasswordsReset.spec.js +++ b/spec/ValidationAndPasswordsReset.spec.js @@ -1082,4 +1082,43 @@ describe('Custom Pages, Email Verification, Password Reset', () => { done(); }); }); + + it('should throw on an invalid reset password', async () => { + await reconfigureServer({ + appName: 'coolapp', + publicServerURL: 'http://localhost:1337/1', + emailAdapter: MockEmailAdapterWithOptions({ + fromAddress: 'parse@example.com', + apiKey: 'k', + domain: 'd', + }), + passwordPolicy: { + resetPasswordSuccessOnInvalidEmail: false, + }, + }); + + await expectAsync(Parse.User.requestPasswordReset('test@example.com')).toBeRejectedWith( + new Parse.Error(Parse.Error.OBJECT_NOT_FOUND, 'A user with that email does not exist.') + ); + }); + + it('validate resetPasswordSuccessonInvalidEmail', async () => { + const invalidValues = [[], {}, 1, 'string']; + for (const value of invalidValues) { + await expectAsync( + reconfigureServer({ + appName: 'coolapp', + publicServerURL: 'http://localhost:1337/1', + emailAdapter: MockEmailAdapterWithOptions({ + fromAddress: 'parse@example.com', + apiKey: 'k', + domain: 'd', + }), + passwordPolicy: { + resetPasswordSuccessOnInvalidEmail: value, + }, + }) + ).toBeRejectedWith('resetPasswordSuccessOnInvalidEmail must be a boolean value'); + } + }); }); diff --git a/src/Config.js b/src/Config.js index bd7c6f21af..c993e467fb 100644 --- a/src/Config.js +++ b/src/Config.js @@ -376,6 +376,13 @@ export class Config { if (passwordPolicy.resetTokenReuseIfValid && !passwordPolicy.resetTokenValidityDuration) { throw 'You cannot use resetTokenReuseIfValid without resetTokenValidityDuration'; } + + if ( + passwordPolicy.resetPasswordSuccessOnInvalidEmail && + typeof passwordPolicy.resetPasswordSuccessOnInvalidEmail !== 'boolean' + ) { + throw 'resetPasswordSuccessOnInvalidEmail must be a boolean value'; + } } } diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index f7a4f822d7..2d53cc7c27 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -907,6 +907,13 @@ module.exports.PasswordPolicyOptions = { 'Set the number of previous password that will not be allowed to be set as new password. If the option is not set or set to `0`, no previous passwords will be considered.

Valid values are >= `0` and <= `20`.
Default is `0`.', action: parsers.numberParser('maxPasswordHistory'), }, + resetPasswordSuccessOnInvalidEmail: { + env: 'PARSE_SERVER_PASSWORD_POLICY_RESET_PASSWORD_SUCCESS_ON_INVALID_EMAIL', + help: + 'Set to `true` if a request to reset the password should return a success response even if the provided email address is invalid, or `false` if the request should return an error response if the email address is invalid.

Default is `true`.', + action: parsers.booleanParser, + default: true, + }, resetTokenReuseIfValid: { env: 'PARSE_SERVER_PASSWORD_POLICY_RESET_TOKEN_REUSE_IF_VALID', help: diff --git a/src/Options/docs.js b/src/Options/docs.js index b0378d327e..0f28270f56 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -207,6 +207,7 @@ * @property {Boolean} doNotAllowUsername Set to `true` to disallow the username as part of the password.

Default is `false`. * @property {Number} maxPasswordAge Set the number of days after which a password expires. Login attempts fail if the user does not reset the password before expiration. * @property {Number} maxPasswordHistory Set the number of previous password that will not be allowed to be set as new password. If the option is not set or set to `0`, no previous passwords will be considered.

Valid values are >= `0` and <= `20`.
Default is `0`. + * @property {Boolean} resetPasswordSuccessOnInvalidEmail Set to `true` if a request to reset the password should return a success response even if the provided email address is invalid, or `false` if the request should return an error response if the email address is invalid.

Default is `true`. * @property {Boolean} resetTokenReuseIfValid Set to `true` if a password reset token should be reused in case another token is requested but there is a token that is still valid, i.e. has not expired. This avoids the often observed issue that a user requests multiple emails and does not know which link contains a valid token because each newly generated token would invalidate the previous token.

Default is `false`. * @property {Number} resetTokenValidityDuration Set the validity duration of the password reset token in seconds after which the token expires. The token is used in the link that is set in the email. After the token expires, the link becomes invalid and a new link has to be sent. If the option is not set or set to `undefined`, then the token never expires.

For example, to expire the token after 2 hours, set a value of 7200 seconds (= 60 seconds * 60 minutes * 2 hours).

Default is `undefined`. * @property {String} validationError Set the error message to be sent.

Default is `Password does not meet the Password Policy requirements.` diff --git a/src/Options/index.js b/src/Options/index.js index 661d062de6..6d0f488b88 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -525,6 +525,11 @@ export interface PasswordPolicyOptions { Default is `false`. :DEFAULT: false */ resetTokenReuseIfValid: ?boolean; + /* Set to `true` if a request to reset the password should return a success response even if the provided email address is invalid, or `false` if the request should return an error response if the email address is invalid. +

+ Default is `true`. + :DEFAULT: true */ + resetPasswordSuccessOnInvalidEmail: ?boolean; } export interface FileUploadOptions { diff --git a/src/Routers/UsersRouter.js b/src/Routers/UsersRouter.js index a0c0039c47..4a72fdd73b 100644 --- a/src/Routers/UsersRouter.js +++ b/src/Routers/UsersRouter.js @@ -414,7 +414,7 @@ export class UsersRouter extends ClassesRouter { } } - handleResetRequest(req) { + async handleResetRequest(req) { this._throwOnBadEmailConfig(req); const { email } = req.body; @@ -428,24 +428,22 @@ export class UsersRouter extends ClassesRouter { ); } const userController = req.config.userController; - return userController.sendPasswordResetEmail(email).then( - () => { - return Promise.resolve({ - response: {}, - }); - }, - err => { - if (err.code === Parse.Error.OBJECT_NOT_FOUND) { - // Return success so that this endpoint can't - // be used to enumerate valid emails - return Promise.resolve({ + try { + await userController.sendPasswordResetEmail(email); + return { + response: {}, + }; + } catch (err) { + if (err.code === Parse.Error.OBJECT_NOT_FOUND) { + if (req.config.passwordPolicy?.resetPasswordSuccessOnInvalidEmail ?? true) { + return { response: {}, - }); - } else { - throw err; + }; } + err.message = `A user with that email does not exist.`; } - ); + throw err; + } } handleVerificationEmailRequest(req) { From bdca9f4ce39498d66ac51de576359d4d929148b2 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Fri, 24 Feb 2023 19:32:10 +0000 Subject: [PATCH 11/14] chore(release): 6.0.0-alpha.34 [skip ci] # [6.0.0-alpha.34](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.33...6.0.0-alpha.34) (2023-02-24) ### Features * Add Parse Server option `resetPasswordSuccessOnInvalidEmail` to choose success or error response on password reset with invalid email ([#7551](https://github.com/parse-community/parse-server/issues/7551)) ([e5d610e](https://github.com/parse-community/parse-server/commit/e5d610e5e487ddab86409409ac3d7362aba8f59b)) --- changelogs/CHANGELOG_alpha.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/changelogs/CHANGELOG_alpha.md b/changelogs/CHANGELOG_alpha.md index 74510e0a3f..8f00de0ede 100644 --- a/changelogs/CHANGELOG_alpha.md +++ b/changelogs/CHANGELOG_alpha.md @@ -1,3 +1,10 @@ +# [6.0.0-alpha.34](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.33...6.0.0-alpha.34) (2023-02-24) + + +### Features + +* Add Parse Server option `resetPasswordSuccessOnInvalidEmail` to choose success or error response on password reset with invalid email ([#7551](https://github.com/parse-community/parse-server/issues/7551)) ([e5d610e](https://github.com/parse-community/parse-server/commit/e5d610e5e487ddab86409409ac3d7362aba8f59b)) + # [6.0.0-alpha.33](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.32...6.0.0-alpha.33) (2023-02-17) diff --git a/package-lock.json b/package-lock.json index 767d98cbce..fcc0839bcf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "parse-server", - "version": "6.0.0-alpha.33", + "version": "6.0.0-alpha.34", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "parse-server", - "version": "6.0.0-alpha.33", + "version": "6.0.0-alpha.34", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 2e5eb8590c..5a809202d7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "parse-server", - "version": "6.0.0-alpha.33", + "version": "6.0.0-alpha.34", "description": "An express module providing a Parse-compatible API server", "main": "lib/index.js", "repository": { From b3b76de71b1d4265689d052e7837c38ec1fa4323 Mon Sep 17 00:00:00 2001 From: Daniel Date: Mon, 27 Feb 2023 11:55:47 +1100 Subject: [PATCH 12/14] feat: Add option `schemaCacheTtl` for schema cache pulling as alternative to `enableSchemaHooks` (#8436) --- spec/SchemaPerformance.spec.js | 54 ++++++++++++++++ .../Storage/Mongo/MongoStorageAdapter.js | 10 ++- .../Postgres/PostgresStorageAdapter.js | 9 ++- src/Adapters/Storage/StorageAdapter.js | 2 + src/Config.js | 63 +++++++++++++------ src/Controllers/SchemaController.js | 28 ++++++++- src/Options/Definitions.js | 6 ++ src/Options/docs.js | 1 + src/Options/index.js | 2 + src/ParseServer.js | 1 + 10 files changed, 150 insertions(+), 26 deletions(-) diff --git a/spec/SchemaPerformance.spec.js b/spec/SchemaPerformance.spec.js index 0471871c54..17238b0ed6 100644 --- a/spec/SchemaPerformance.spec.js +++ b/spec/SchemaPerformance.spec.js @@ -204,4 +204,58 @@ describe('Schema Performance', function () { ); expect(getAllSpy.calls.count()).toBe(2); }); + + it('does reload with schemaCacheTtl', async () => { + const databaseURI = + process.env.PARSE_SERVER_TEST_DB === 'postgres' + ? process.env.PARSE_SERVER_TEST_DATABASE_URI + : 'mongodb://localhost:27017/parseServerMongoAdapterTestDatabase'; + await reconfigureServer({ + databaseAdapter: undefined, + databaseURI, + silent: false, + databaseOptions: { schemaCacheTtl: 1000 }, + }); + const SchemaController = require('../lib/Controllers/SchemaController').SchemaController; + const spy = spyOn(SchemaController.prototype, 'reloadData').and.callThrough(); + Object.defineProperty(spy, 'reloadCalls', { + get: () => spy.calls.all().filter(call => call.args[0].clearCache).length, + }); + + const object = new TestObject(); + object.set('foo', 'bar'); + await object.save(); + + spy.calls.reset(); + + object.set('foo', 'bar'); + await object.save(); + + expect(spy.reloadCalls).toBe(0); + + await new Promise(resolve => setTimeout(resolve, 1100)); + + object.set('foo', 'bar'); + await object.save(); + + expect(spy.reloadCalls).toBe(1); + }); + + it('cannot set invalid databaseOptions', async () => { + const expectError = async (key, value, expected) => + expectAsync( + reconfigureServer({ databaseAdapter: undefined, databaseOptions: { [key]: value } }) + ).toBeRejectedWith(`databaseOptions.${key} must be a ${expected}`); + for (const databaseOptions of [[], 0, 'string']) { + await expectAsync( + reconfigureServer({ databaseAdapter: undefined, databaseOptions }) + ).toBeRejectedWith(`databaseOptions must be an object`); + } + for (const value of [null, 0, 'string', {}, []]) { + await expectError('enableSchemaHooks', value, 'boolean'); + } + for (const value of [null, false, 'string', {}, []]) { + await expectError('schemaCacheTtl', value, 'number'); + } + }); }); diff --git a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js index c0d4c0ca9e..78833a026b 100644 --- a/src/Adapters/Storage/Mongo/MongoStorageAdapter.js +++ b/src/Adapters/Storage/Mongo/MongoStorageAdapter.js @@ -139,11 +139,12 @@ export class MongoStorageAdapter implements StorageAdapter { _maxTimeMS: ?number; canSortOnJoinTables: boolean; enableSchemaHooks: boolean; + schemaCacheTtl: ?number; constructor({ uri = defaults.DefaultMongoURI, collectionPrefix = '', mongoOptions = {} }: any) { this._uri = uri; this._collectionPrefix = collectionPrefix; - this._mongoOptions = mongoOptions; + this._mongoOptions = { ...mongoOptions }; this._mongoOptions.useNewUrlParser = true; this._mongoOptions.useUnifiedTopology = true; this._onchange = () => {}; @@ -152,8 +153,11 @@ export class MongoStorageAdapter implements StorageAdapter { this._maxTimeMS = mongoOptions.maxTimeMS; this.canSortOnJoinTables = true; this.enableSchemaHooks = !!mongoOptions.enableSchemaHooks; - delete mongoOptions.enableSchemaHooks; - delete mongoOptions.maxTimeMS; + this.schemaCacheTtl = mongoOptions.schemaCacheTtl; + for (const key of ['enableSchemaHooks', 'schemaCacheTtl', 'maxTimeMS']) { + delete mongoOptions[key]; + delete this._mongoOptions[key]; + } } watch(callback: () => void): void { diff --git a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js index 444e4e8cca..82ac0c20dc 100644 --- a/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js +++ b/src/Adapters/Storage/Postgres/PostgresStorageAdapter.js @@ -850,13 +850,18 @@ export class PostgresStorageAdapter implements StorageAdapter { _pgp: any; _stream: any; _uuid: any; + schemaCacheTtl: ?number; constructor({ uri, collectionPrefix = '', databaseOptions = {} }: any) { + const options = { ...databaseOptions }; this._collectionPrefix = collectionPrefix; this.enableSchemaHooks = !!databaseOptions.enableSchemaHooks; - delete databaseOptions.enableSchemaHooks; + this.schemaCacheTtl = databaseOptions.schemaCacheTtl; + for (const key of ['enableSchemaHooks', 'schemaCacheTtl']) { + delete options[key]; + } - const { client, pgp } = createClient(uri, databaseOptions); + const { client, pgp } = createClient(uri, options); this._client = client; this._onchange = () => {}; this._pgp = pgp; diff --git a/src/Adapters/Storage/StorageAdapter.js b/src/Adapters/Storage/StorageAdapter.js index 6e4573b748..7605784a43 100644 --- a/src/Adapters/Storage/StorageAdapter.js +++ b/src/Adapters/Storage/StorageAdapter.js @@ -30,6 +30,8 @@ export type FullQueryOptions = QueryOptions & UpdateQueryOptions; export interface StorageAdapter { canSortOnJoinTables: boolean; + schemaCacheTtl: ?number; + enableSchemaHooks: boolean; classExists(className: string): Promise; setClassLevelPermissions(className: string, clps: any): Promise; diff --git a/src/Config.js b/src/Config.js index c993e467fb..2e7ef389c7 100644 --- a/src/Config.js +++ b/src/Config.js @@ -9,6 +9,7 @@ import DatabaseController from './Controllers/DatabaseController'; import { logLevels as validLogLevels } from './Controllers/LoggerController'; import { AccountLockoutOptions, + DatabaseOptions, FileUploadOptions, IdempotencyOptions, LogLevels, @@ -52,23 +53,20 @@ export class Config { } static put(serverConfiguration) { - Config.validate(serverConfiguration); + Config.validateOptions(serverConfiguration); + Config.validateControllers(serverConfiguration); AppCache.put(serverConfiguration.appId, serverConfiguration); Config.setupPasswordValidator(serverConfiguration.passwordPolicy); return serverConfiguration; } - static validate({ - verifyUserEmails, - userController, - appName, + static validateOptions({ publicServerURL, revokeSessionOnPasswordReset, expireInactiveSessions, sessionLength, defaultLimit, maxLimit, - emailVerifyTokenValidityDuration, accountLockout, passwordPolicy, masterKeyIps, @@ -78,7 +76,6 @@ export class Config { readOnlyMasterKey, allowHeaders, idempotencyOptions, - emailVerifyTokenReuseIfValid, fileUpload, pages, security, @@ -88,6 +85,7 @@ export class Config { allowExpiredAuthDataToken, logLevels, rateLimit, + databaseOptions, }) { if (masterKey === readOnlyMasterKey) { throw new Error('masterKey and readOnlyMasterKey should be different'); @@ -97,17 +95,6 @@ export class Config { throw new Error('masterKey and maintenanceKey should be different'); } - const emailAdapter = userController.adapter; - if (verifyUserEmails) { - this.validateEmailConfiguration({ - emailAdapter, - appName, - publicServerURL, - emailVerifyTokenValidityDuration, - emailVerifyTokenReuseIfValid, - }); - } - this.validateAccountLockoutPolicy(accountLockout); this.validatePasswordPolicy(passwordPolicy); this.validateFileUploadOptions(fileUpload); @@ -136,6 +123,27 @@ export class Config { this.validateRequestKeywordDenylist(requestKeywordDenylist); this.validateRateLimit(rateLimit); this.validateLogLevels(logLevels); + this.validateDatabaseOptions(databaseOptions); + } + + static validateControllers({ + verifyUserEmails, + userController, + appName, + publicServerURL, + emailVerifyTokenValidityDuration, + emailVerifyTokenReuseIfValid, + }) { + const emailAdapter = userController.adapter; + if (verifyUserEmails) { + this.validateEmailConfiguration({ + emailAdapter, + appName, + publicServerURL, + emailVerifyTokenValidityDuration, + emailVerifyTokenReuseIfValid, + }); + } } static validateRequestKeywordDenylist(requestKeywordDenylist) { @@ -533,6 +541,25 @@ export class Config { } } + static validateDatabaseOptions(databaseOptions) { + if (databaseOptions == undefined) { + return; + } + if (Object.prototype.toString.call(databaseOptions) !== '[object Object]') { + throw `databaseOptions must be an object`; + } + if (databaseOptions.enableSchemaHooks === undefined) { + databaseOptions.enableSchemaHooks = DatabaseOptions.enableSchemaHooks.default; + } else if (typeof databaseOptions.enableSchemaHooks !== 'boolean') { + throw `databaseOptions.enableSchemaHooks must be a boolean`; + } + if (databaseOptions.schemaCacheTtl === undefined) { + databaseOptions.schemaCacheTtl = DatabaseOptions.schemaCacheTtl.default; + } else if (typeof databaseOptions.schemaCacheTtl !== 'number') { + throw `databaseOptions.schemaCacheTtl must be a number`; + } + } + static validateRateLimit(rateLimit) { if (!rateLimit) { return; diff --git a/src/Controllers/SchemaController.js b/src/Controllers/SchemaController.js index 62757d251d..ad3699aaa5 100644 --- a/src/Controllers/SchemaController.js +++ b/src/Controllers/SchemaController.js @@ -682,6 +682,10 @@ const typeToString = (type: SchemaField | string): string => { } return `${type.type}`; }; +const ttl = { + date: Date.now(), + duration: undefined, +}; // Stores the entire schema of the app in a weird hybrid format somewhere between // the mongo format and the Parse format. Soon, this will all be Parse format. @@ -694,10 +698,11 @@ export default class SchemaController { constructor(databaseAdapter: StorageAdapter) { this._dbAdapter = databaseAdapter; + const config = Config.get(Parse.applicationId); this.schemaData = new SchemaData(SchemaCache.all(), this.protectedFields); - this.protectedFields = Config.get(Parse.applicationId).protectedFields; + this.protectedFields = config.protectedFields; - const customIds = Config.get(Parse.applicationId).allowCustomObjectId; + const customIds = config.allowCustomObjectId; const customIdRegEx = /^.{1,}$/u; // 1+ chars const autoIdRegEx = /^[a-zA-Z0-9]{1,}$/; @@ -709,6 +714,21 @@ export default class SchemaController { }); } + async reloadDataIfNeeded() { + if (this._dbAdapter.enableSchemaHooks) { + return; + } + const { date, duration } = ttl || {}; + if (!duration) { + return; + } + const now = Date.now(); + if (now - date > duration) { + ttl.date = now; + await this.reloadData({ clearCache: true }); + } + } + reloadData(options: LoadSchemaOptions = { clearCache: false }): Promise { if (this.reloadDataPromise && !options.clearCache) { return this.reloadDataPromise; @@ -729,10 +749,11 @@ export default class SchemaController { return this.reloadDataPromise; } - getAllClasses(options: LoadSchemaOptions = { clearCache: false }): Promise> { + async getAllClasses(options: LoadSchemaOptions = { clearCache: false }): Promise> { if (options.clearCache) { return this.setAllClasses(); } + await this.reloadDataIfNeeded(); const cached = SchemaCache.all(); if (cached && cached.length) { return Promise.resolve(cached); @@ -1440,6 +1461,7 @@ export default class SchemaController { // Returns a promise for a new Schema. const load = (dbAdapter: StorageAdapter, options: any): Promise => { const schema = new SchemaController(dbAdapter); + ttl.duration = dbAdapter.schemaCacheTtl; return schema.reloadData(options).then(() => schema); }; diff --git a/src/Options/Definitions.js b/src/Options/Definitions.js index 2d53cc7c27..a25e69c70a 100644 --- a/src/Options/Definitions.js +++ b/src/Options/Definitions.js @@ -971,6 +971,12 @@ module.exports.DatabaseOptions = { action: parsers.booleanParser, default: false, }, + schemaCacheTtl: { + env: 'PARSE_SERVER_DATABASE_SCHEMA_CACHE_TTL', + help: + 'The duration in seconds after which the schema cache expires and will be refetched from the database. Use this option if using multiple Parse Servers instances connected to the same database. A low duration will cause the schema cache to be updated too often, causing unnecessary database reads. A high duration will cause the schema to be updated too rarely, increasing the time required until schema changes propagate to all server instances. This feature can be used as an alternative or in conjunction with the option `enableSchemaHooks`. Default is infinite which means the schema cache never expires.', + action: parsers.numberParser('schemaCacheTtl'), + }, }; module.exports.AuthAdapter = { enabled: { diff --git a/src/Options/docs.js b/src/Options/docs.js index 0f28270f56..0eb6488c74 100644 --- a/src/Options/docs.js +++ b/src/Options/docs.js @@ -225,6 +225,7 @@ /** * @interface DatabaseOptions * @property {Boolean} enableSchemaHooks Enables database real-time hooks to update single schema cache. Set to `true` if using multiple Parse Servers instances connected to the same database. Failing to do so will cause a schema change to not propagate to all instances and re-syncing will only happen when the instances restart. To use this feature with MongoDB, a replica set cluster with [change stream](https://docs.mongodb.com/manual/changeStreams/#availability) support is required. + * @property {Number} schemaCacheTtl The duration in seconds after which the schema cache expires and will be refetched from the database. Use this option if using multiple Parse Servers instances connected to the same database. A low duration will cause the schema cache to be updated too often, causing unnecessary database reads. A high duration will cause the schema to be updated too rarely, increasing the time required until schema changes propagate to all server instances. This feature can be used as an alternative or in conjunction with the option `enableSchemaHooks`. Default is infinite which means the schema cache never expires. */ /** diff --git a/src/Options/index.js b/src/Options/index.js index 6d0f488b88..778374e7e7 100644 --- a/src/Options/index.js +++ b/src/Options/index.js @@ -548,6 +548,8 @@ export interface DatabaseOptions { /* Enables database real-time hooks to update single schema cache. Set to `true` if using multiple Parse Servers instances connected to the same database. Failing to do so will cause a schema change to not propagate to all instances and re-syncing will only happen when the instances restart. To use this feature with MongoDB, a replica set cluster with [change stream](https://docs.mongodb.com/manual/changeStreams/#availability) support is required. :DEFAULT: false */ enableSchemaHooks: ?boolean; + /* The duration in seconds after which the schema cache expires and will be refetched from the database. Use this option if using multiple Parse Servers instances connected to the same database. A low duration will cause the schema cache to be updated too often, causing unnecessary database reads. A high duration will cause the schema to be updated too rarely, increasing the time required until schema changes propagate to all server instances. This feature can be used as an alternative or in conjunction with the option `enableSchemaHooks`. Default is infinite which means the schema cache never expires. */ + schemaCacheTtl: ?number; } export interface AuthAdapter { diff --git a/src/ParseServer.js b/src/ParseServer.js index ed21ce12e3..04379ecfd3 100644 --- a/src/ParseServer.js +++ b/src/ParseServer.js @@ -71,6 +71,7 @@ class ParseServer { Parse.initialize(appId, javascriptKey || 'unused', masterKey); Parse.serverURL = serverURL; + Config.validateOptions(options); const allControllers = controllers.getControllers(options); options.state = 'initialized'; this.config = Config.put(Object.assign({}, options, allControllers)); From e9ab6b055d5ddc09c3b50e269888118da17ca9f2 Mon Sep 17 00:00:00 2001 From: semantic-release-bot Date: Mon, 27 Feb 2023 00:56:49 +0000 Subject: [PATCH 13/14] chore(release): 6.0.0-alpha.35 [skip ci] # [6.0.0-alpha.35](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.34...6.0.0-alpha.35) (2023-02-27) ### Features * Add option `schemaCacheTtl` for schema cache pulling as alternative to `enableSchemaHooks` ([#8436](https://github.com/parse-community/parse-server/issues/8436)) ([b3b76de](https://github.com/parse-community/parse-server/commit/b3b76de71b1d4265689d052e7837c38ec1fa4323)) --- changelogs/CHANGELOG_alpha.md | 7 +++++++ package-lock.json | 4 ++-- package.json | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/changelogs/CHANGELOG_alpha.md b/changelogs/CHANGELOG_alpha.md index 8f00de0ede..18eb32b574 100644 --- a/changelogs/CHANGELOG_alpha.md +++ b/changelogs/CHANGELOG_alpha.md @@ -1,3 +1,10 @@ +# [6.0.0-alpha.35](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.34...6.0.0-alpha.35) (2023-02-27) + + +### Features + +* Add option `schemaCacheTtl` for schema cache pulling as alternative to `enableSchemaHooks` ([#8436](https://github.com/parse-community/parse-server/issues/8436)) ([b3b76de](https://github.com/parse-community/parse-server/commit/b3b76de71b1d4265689d052e7837c38ec1fa4323)) + # [6.0.0-alpha.34](https://github.com/parse-community/parse-server/compare/6.0.0-alpha.33...6.0.0-alpha.34) (2023-02-24) diff --git a/package-lock.json b/package-lock.json index fcc0839bcf..3e358c410e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "parse-server", - "version": "6.0.0-alpha.34", + "version": "6.0.0-alpha.35", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "parse-server", - "version": "6.0.0-alpha.34", + "version": "6.0.0-alpha.35", "hasInstallScript": true, "license": "Apache-2.0", "dependencies": { diff --git a/package.json b/package.json index 5a809202d7..45e9802fc2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "parse-server", - "version": "6.0.0-alpha.34", + "version": "6.0.0-alpha.35", "description": "An express module providing a Parse-compatible API server", "main": "lib/index.js", "repository": { From a74b7c2f7479e31b73d555e5245d45b1e3d5682d Mon Sep 17 00:00:00 2001 From: Manuel <5673677+mtrezza@users.noreply.github.com> Date: Wed, 1 Mar 2023 17:28:17 +0100 Subject: [PATCH 14/14] ci: Remove release-automated-scheduler (#8450) --- .../workflows/release-automated-scheduler.yml | 74 ------------------- 1 file changed, 74 deletions(-) delete mode 100644 .github/workflows/release-automated-scheduler.yml diff --git a/.github/workflows/release-automated-scheduler.yml b/.github/workflows/release-automated-scheduler.yml deleted file mode 100644 index d67b102e27..0000000000 --- a/.github/workflows/release-automated-scheduler.yml +++ /dev/null @@ -1,74 +0,0 @@ -# This scheduler creates pull requests to prepare for releases in intervals according to the -# release cycle of this repository. - -name: release-automated-scheduler -on: -# Scheduler temporarily disabled until stable release of Parse Server 5 with all branches (alpha, beta, release) created -# schedule: -# - cron: 0 0 1 * * - workflow_dispatch: - -jobs: - create-pr-release: - runs-on: ubuntu-latest - steps: - - name: Checkout beta branch - uses: actions/checkout@v2 - with: - ref: beta - - name: Compose branch name for PR - id: branch - run: echo "::set-output name=name::build-release-${{ github.run_id }}${{ github.run_number }}" - - name: Create branch - run: | - git config --global user.email ${{ github.actor }}@users.noreply.github.com - git config --global user.name ${{ github.actor }} - git checkout -b ${{ steps.branch.outputs.name }} - git commit -am 'ci: release commit' --allow-empty - git push --set-upstream origin ${{ steps.branch.outputs.name }} - - name: Create PR - uses: k3rnels-actions/pr-update@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - pr_title: "build: release" - pr_source: ${{ steps.branch.outputs.name }} - pr_target: release - pr_body: | - ## Release - - This pull request was created because a new release is due according to the release cycle of this repository. - Just resolve any conflicts and it's good to merge. Any version increment will be done by release automation. - - *⚠️ Use `Merge commit` to merge this pull request. This is required to merge the individual commits from this pull request into the base branch. Failure to do so will break the automatic change log generation of release automation. Do not use "Squash and merge"!* - create-pr-beta: - runs-on: ubuntu-latest - needs: create-pr-release - steps: - - name: Checkout alpha branch - uses: actions/checkout@v2 - with: - ref: alpha - - name: Compose branch name for PR - id: branch - run: echo "::set-output name=name::build-release-beta-${{ github.run_id }}${{ github.run_number }}" - - name: Create branch - run: | - git config --global user.email ${{ github.actor }}@users.noreply.github.com - git config --global user.name ${{ github.actor }} - git checkout -b ${{ steps.branch.outputs.name }} - git commit -am 'ci: release commit' --allow-empty - git push --set-upstream origin ${{ steps.branch.outputs.name }} - - name: Create PR - uses: k3rnels-actions/pr-update@v1 - with: - token: ${{ secrets.GITHUB_TOKEN }} - pr_title: "build: release beta" - pr_source: ${{ steps.branch.outputs.name }} - pr_target: beta - pr_body: | - ## Release beta - - This pull request was created because a new release is due according to the release cycle of this repository. - Just resolve any conflicts and it's good to merge. Any version increment will be done by release automation. - - *⚠️ Use `Merge commit` to merge this pull request. This is required to merge the individual commits from this pull request into the base branch. Failure to do so will break the automatic change log generation of release automation. Do not use "Squash and merge"!*