From d1291faf3e26e178b9697d0c4de5a09550a04135 Mon Sep 17 00:00:00 2001 From: Lucas Leblow Date: Tue, 14 Nov 2023 16:26:43 -0700 Subject: [PATCH] feat: Add community metadata validation Validate that the community metadata is only written to by the owner and refactor it into it's own store class. --- packages/backend/package-lock.json | 3599 ++++++++++------- packages/backend/package.json | 291 +- packages/backend/src/backendManager.ts | 3 +- .../connections-manager.service.ts | 47 +- .../src/nest/local-db/local-db.service.ts | 8 + .../src/nest/local-db/local-db.types.ts | 1 + .../nest/registration/registration.service.ts | 7 +- .../backend/src/nest/socket/socket.service.ts | 2 +- .../communityMetadata.store.spec.ts | 151 + .../communityMetadata.store.ts | 222 + .../storage/orbitDb/keyValueIndex.spec.ts | 44 + .../src/nest/storage/orbitDb/keyValueIndex.ts | 63 + .../src/nest/storage/storage.service.spec.ts | 3 +- .../src/nest/storage/storage.service.ts | 87 +- .../backend/src/nest/storage/storage.types.ts | 4 +- packages/common/package-lock.json | 154 - packages/common/src/invitationCode.test.ts | 7 +- packages/common/src/invitationCode.ts | 21 +- packages/common/src/tests.ts | 2 + packages/desktop/src/main/main.ts | 8 +- .../JoinCommunity/JoinCommunity.tsx | 1 + .../PerformCommunityActionComponent.tsx | 10 +- .../components/Settings/Settings.stories.tsx | 1 + .../Tabs/Invite/Invite.component.test.tsx | 2 + .../Settings/Tabs/Invite/Invite.stories.tsx | 1 + .../Settings/Tabs/QRCode/QRCode.stories.tsx | 1 + .../invitation/customProtocol.saga.test.ts | 2 + .../sagas/invitation/customProtocol.saga.ts | 3 +- .../src/rtl-tests/community.join.test.tsx | 1 + .../src/rtl-tests/customProtocol.test.tsx | 1 + packages/identity/src/createUserCert.ts | 4 +- .../JoinCommunity/JoinCommunity.screen.tsx | 1 + .../store/init/deepLink/deepLink.saga.test.ts | 6 + .../src/store/init/deepLink/deepLink.saga.ts | 1 + .../communities/communities.selectors.test.ts | 4 +- .../communities/communities.selectors.ts | 23 +- .../sagas/communities/communities.slice.ts | 7 +- .../sagas/communities/communities.types.ts | 5 - .../createNetwork/createNetwork.saga.ts | 1 + .../saveCommunityMetadata.saga.ts | 1 + .../updateCommunity/updateCommunity.saga.ts | 37 +- .../registerUsername.saga.test.ts | 2 + .../registerUsername/registerUsername.saga.ts | 5 + .../startConnection/startConnection.saga.ts | 18 +- .../invitationCode/invitationCode.test.ts | 13 +- packages/types/src/community.ts | 16 +- packages/types/src/errors.ts | 1 + packages/types/src/network.ts | 1 + packages/types/src/socket.ts | 2 +- 49 files changed, 3023 insertions(+), 1872 deletions(-) create mode 100644 packages/backend/src/nest/storage/communityMetadata/communityMetadata.store.spec.ts create mode 100644 packages/backend/src/nest/storage/communityMetadata/communityMetadata.store.ts create mode 100644 packages/backend/src/nest/storage/orbitDb/keyValueIndex.spec.ts create mode 100644 packages/backend/src/nest/storage/orbitDb/keyValueIndex.ts diff --git a/packages/backend/package-lock.json b/packages/backend/package-lock.json index 4323d96834..db6bcd88d9 100644 --- a/packages/backend/package-lock.json +++ b/packages/backend/package-lock.json @@ -11,9 +11,9 @@ "dependencies": { "@chainsafe/libp2p-gossipsub": "6.1.0", "@chainsafe/libp2p-noise": "11.0.0", - "@nestjs/common": "^10.0.0", - "@nestjs/core": "^10.0.0", - "@nestjs/platform-express": "^10.0.0", + "@nestjs/common": "^10.2.10", + "@nestjs/core": "^10.2.10", + "@nestjs/platform-express": "^10.2.10", "@peculiar/webcrypto": "1.4.3", "abortable-iterator": "^3.0.0", "class-transformer": "^0.5.1", @@ -59,9 +59,9 @@ "validator": "^13.11.0" }, "devDependencies": { - "@nestjs/cli": "^10.0.0", - "@nestjs/schematics": "^10.0.0", - "@nestjs/testing": "^10.0.0", + "@nestjs/cli": "^10.2.1", + "@nestjs/schematics": "^10.0.3", + "@nestjs/testing": "^10.2.10", "@types/crypto-js": "^4.0.2", "@types/express": "^4.17.9", "@types/jest": "28.1.8", @@ -293,194 +293,6 @@ "uuid": "dist/bin/uuid" } }, - "node_modules/@angular-devkit/core": { - "version": "16.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.0", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@angular-devkit/core/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@angular-devkit/core/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, - "node_modules/@angular-devkit/core/node_modules/source-map": { - "version": "0.7.4", - "dev": true, - "license": "BSD-3-Clause", - "engines": { - "node": ">= 8" - } - }, - "node_modules/@angular-devkit/schematics": { - "version": "16.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "16.1.0", - "jsonc-parser": "3.2.0", - "magic-string": "0.30.0", - "ora": "5.4.1", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/schematics-cli": { - "version": "16.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@angular-devkit/core": "16.1.0", - "@angular-devkit/schematics": "16.1.0", - "ansi-colors": "4.1.3", - "inquirer": "8.2.4", - "symbol-observable": "4.0.0", - "yargs-parser": "21.1.1" - }, - "bin": { - "schematics": "bin/schematics.js" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/inquirer": { - "version": "8.2.4", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@angular-devkit/schematics-cli/node_modules/yargs-parser": { - "version": "21.1.1", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=12" - } - }, "node_modules/@assemblyscript/loader": { "version": "0.9.4", "license": "Apache-2.0" @@ -4889,20 +4701,22 @@ } }, "node_modules/@nestjs/cli": { - "version": "10.0.3", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.2.1.tgz", + "integrity": "sha512-CAJAQwmxFZfB3RTvqz/eaXXWpyU+mZ4QSqfBYzjneTsPgF+uyOAW3yQpaLNn9Dfcv39R9UxSuAhayv6yuFd+Jg==", "dev": true, - "license": "MIT", "dependencies": { - "@angular-devkit/core": "16.1.0", - "@angular-devkit/schematics": "16.1.0", - "@angular-devkit/schematics-cli": "16.1.0", + "@angular-devkit/core": "16.2.8", + "@angular-devkit/schematics": "16.2.8", + "@angular-devkit/schematics-cli": "16.2.8", "@nestjs/schematics": "^10.0.1", "chalk": "4.1.2", "chokidar": "3.5.3", "cli-table3": "0.6.3", "commander": "4.1.1", - "fork-ts-checker-webpack-plugin": "8.0.0", - "inquirer": "8.2.5", + "fork-ts-checker-webpack-plugin": "9.0.2", + "glob": "10.3.10", + "inquirer": "8.2.6", "node-emoji": "1.11.0", "ora": "5.4.1", "os-name": "4.0.1", @@ -4911,16 +4725,16 @@ "source-map-support": "0.5.21", "tree-kill": "1.2.2", "tsconfig-paths": "4.2.0", - "tsconfig-paths-webpack-plugin": "4.0.1", - "typescript": "5.1.3", - "webpack": "5.87.0", + "tsconfig-paths-webpack-plugin": "4.1.0", + "typescript": "5.2.2", + "webpack": "5.89.0", "webpack-node-externals": "3.0.0" }, "bin": { "nest": "bin/nest.js" }, "engines": { - "node": ">= 16" + "node": ">= 16.14" }, "peerDependencies": { "@swc/cli": "^0.1.62", @@ -4935,15 +4749,382 @@ } } }, - "node_modules/@nestjs/cli/node_modules/@types/estree": { - "version": "1.0.1", + "node_modules/@nestjs/cli/node_modules/@angular-devkit/core": { + "version": "16.2.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.8.tgz", + "integrity": "sha512-PTGozYvh1Bin5lB15PwcXa26Ayd17bWGLS3H8Rs0s+04mUDvfNofmweaX1LgumWWy3nCUTDuwHxX10M3G0wE2g==", "dev": true, - "license": "MIT" + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "2.3.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@nestjs/cli/node_modules/@angular-devkit/schematics": { + "version": "16.2.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.2.8.tgz", + "integrity": "sha512-MBiKZOlR9/YMdflALr7/7w/BGAfo/BGTrlkqsIB6rDWV1dYiCgxI+033HsiNssLS6RQyCFx/e7JA2aBBzu9zEg==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "16.2.8", + "jsonc-parser": "3.2.0", + "magic-string": "0.30.1", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@nestjs/cli/node_modules/@angular-devkit/schematics-cli": { + "version": "16.2.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-16.2.8.tgz", + "integrity": "sha512-EXURJCzWTVYCipiTT4vxQQOrF63asOUDbeOy3OtiSh7EwIUvxm3BPG6hquJqngEnI/N6bA75NJ1fBhU6Hrh7eA==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "16.2.8", + "@angular-devkit/schematics": "16.2.8", + "ansi-colors": "4.1.3", + "inquirer": "8.2.4", + "symbol-observable": "4.0.0", + "yargs-parser": "21.1.1" + }, + "bin": { + "schematics": "bin/schematics.js" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@nestjs/cli/node_modules/@angular-devkit/schematics-cli/node_modules/inquirer": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", + "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@nestjs/cli/node_modules/@babel/code-frame": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", + "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", + "dev": true, + "dependencies": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@nestjs/cli/node_modules/@babel/code-frame/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nestjs/cli/node_modules/@babel/code-frame/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nestjs/cli/node_modules/@babel/code-frame/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@nestjs/cli/node_modules/@babel/code-frame/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@nestjs/cli/node_modules/@babel/code-frame/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nestjs/cli/node_modules/@babel/code-frame/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nestjs/cli/node_modules/@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@nestjs/cli/node_modules/@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "dependencies": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@nestjs/cli/node_modules/@babel/highlight/node_modules/ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nestjs/cli/node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nestjs/cli/node_modules/@babel/highlight/node_modules/color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@nestjs/cli/node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "node_modules/@nestjs/cli/node_modules/@babel/highlight/node_modules/has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nestjs/cli/node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nestjs/cli/node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nestjs/cli/node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@nestjs/cli/node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@nestjs/cli/node_modules/@isaacs/cliui/node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/@nestjs/cli/node_modules/@isaacs/cliui/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@nestjs/cli/node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@nestjs/cli/node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@nestjs/cli/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@nestjs/cli/node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, + "node_modules/@nestjs/cli/node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/ast": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/helper-numbers": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6" @@ -4951,23 +5132,27 @@ }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/helper-api-error": { "version": "1.11.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/helper-buffer": { "version": "1.11.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/helper-numbers": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -4976,13 +5161,15 @@ }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/helper-wasm-section": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -4992,29 +5179,33 @@ }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/ieee754": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, - "license": "MIT", "dependencies": { "@xtuc/ieee754": "^1.2.0" } }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/leb128": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, - "license": "Apache-2.0", "dependencies": { "@xtuc/long": "4.2.2" } }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/utf8": { "version": "1.11.6", - "dev": true, - "license": "MIT" + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/wasm-edit": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -5028,8 +5219,9 @@ }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/wasm-gen": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-wasm-bytecode": "1.11.6", @@ -5040,8 +5232,9 @@ }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/wasm-opt": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-buffer": "1.11.6", @@ -5051,8 +5244,9 @@ }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/wasm-parser": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@webassemblyjs/helper-api-error": "1.11.6", @@ -5064,17 +5258,19 @@ }, "node_modules/@nestjs/cli/node_modules/@webassemblyjs/wast-printer": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, - "license": "MIT", "dependencies": { "@webassemblyjs/ast": "1.11.6", "@xtuc/long": "4.2.2" } }, "node_modules/@nestjs/cli/node_modules/acorn": { - "version": "8.9.0", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true, - "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -5084,12 +5280,55 @@ }, "node_modules/@nestjs/cli/node_modules/acorn-import-assertions": { "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, - "license": "MIT", "peerDependencies": { "acorn": "^8" } }, + "node_modules/@nestjs/cli/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@nestjs/cli/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@nestjs/cli/node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/@nestjs/cli/node_modules/ansi-styles": { "version": "4.3.0", "dev": true, @@ -5104,10 +5343,17 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/@nestjs/cli/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "node_modules/@nestjs/cli/node_modules/brace-expansion": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, - "license": "MIT", "dependencies": { "balanced-match": "^1.0.0" } @@ -5127,6 +5373,21 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/@nestjs/cli/node_modules/chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "node_modules/@nestjs/cli/node_modules/cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, "node_modules/@nestjs/cli/node_modules/color-convert": { "version": "2.0.1", "dev": true, @@ -5151,20 +5412,160 @@ "node": ">= 6" } }, + "node_modules/@nestjs/cli/node_modules/cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "dependencies": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@nestjs/cli/node_modules/es-module-lexer": { - "version": "1.3.0", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", + "dev": true + }, + "node_modules/@nestjs/cli/node_modules/external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", "dev": true, - "license": "MIT" + "dependencies": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@nestjs/cli/node_modules/figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^1.0.5" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@nestjs/cli/node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nestjs/cli/node_modules/fork-ts-checker-webpack-plugin": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-9.0.2.tgz", + "integrity": "sha512-Uochze2R8peoN1XqlSi/rGUkDQpRogtLFocP9+PGu68zk1BDAKXfdeCdyVZpgTk8V8WFVQXdEz426VKjXLO1Gg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cosmiconfig": "^8.2.0", + "deepmerge": "^4.2.2", + "fs-extra": "^10.0.0", + "memfs": "^3.4.1", + "minimatch": "^3.0.4", + "node-abort-controller": "^3.0.1", + "schema-utils": "^3.1.1", + "semver": "^7.3.5", + "tapable": "^2.2.1" + }, + "engines": { + "node": ">=12.13.0", + "yarn": ">=1.0.0" + }, + "peerDependencies": { + "typescript": ">3.6.0", + "webpack": "^5.11.0" + } + }, + "node_modules/@nestjs/cli/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nestjs/cli/node_modules/fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", + "dev": true }, "node_modules/@nestjs/cli/node_modules/glob": { - "version": "9.3.5", + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dev": true, - "license": "ISC", "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nestjs/cli/node_modules/glob/node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -5181,6 +5582,98 @@ "node": ">=8" } }, + "node_modules/@nestjs/cli/node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@nestjs/cli/node_modules/inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@nestjs/cli/node_modules/inquirer/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nestjs/cli/node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, + "node_modules/@nestjs/cli/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/@nestjs/cli/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "node_modules/@nestjs/cli/node_modules/json5": { "version": "2.2.3", "dev": true, @@ -5192,12 +5685,125 @@ "node": ">=6" } }, - "node_modules/@nestjs/cli/node_modules/minimatch": { - "version": "8.0.4", + "node_modules/@nestjs/cli/node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "node_modules/@nestjs/cli/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, - "license": "ISC", "dependencies": { - "brace-expansion": "^2.0.1" + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@nestjs/cli/node_modules/lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "dev": true, + "engines": { + "node": "14 || >=16.14" + } + }, + "node_modules/@nestjs/cli/node_modules/magic-string": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", + "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nestjs/cli/node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/@nestjs/cli/node_modules/minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@nestjs/cli/node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node_modules/@nestjs/cli/node_modules/node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "dev": true + }, + "node_modules/@nestjs/cli/node_modules/os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@nestjs/cli/node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@nestjs/cli/node_modules/parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/@nestjs/cli/node_modules/path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "dependencies": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -5206,6 +5812,45 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@nestjs/cli/node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nestjs/cli/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@nestjs/cli/node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@nestjs/cli/node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/@nestjs/cli/node_modules/rimraf": { "version": "4.4.1", "dev": true, @@ -5223,6 +5868,106 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/@nestjs/cli/node_modules/rimraf/node_modules/glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nestjs/cli/node_modules/rimraf/node_modules/minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nestjs/cli/node_modules/rimraf/node_modules/minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nestjs/cli/node_modules/run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/@nestjs/cli/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@nestjs/cli/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@nestjs/cli/node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@nestjs/cli/node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/@nestjs/cli/node_modules/supports-color": { "version": "7.2.0", "dev": true, @@ -5234,6 +5979,33 @@ "node": ">=8" } }, + "node_modules/@nestjs/cli/node_modules/symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/@nestjs/cli/node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "node_modules/@nestjs/cli/node_modules/tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "dependencies": { + "os-tmpdir": "~1.0.2" + }, + "engines": { + "node": ">=0.6.0" + } + }, "node_modules/@nestjs/cli/node_modules/tsconfig-paths": { "version": "4.2.0", "dev": true, @@ -5247,10 +6019,25 @@ "node": ">=6" } }, + "node_modules/@nestjs/cli/node_modules/tsconfig-paths-webpack-plugin": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz", + "integrity": "sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.7.0", + "tsconfig-paths": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, "node_modules/@nestjs/cli/node_modules/typescript": { - "version": "5.1.3", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", "dev": true, - "license": "Apache-2.0", "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -5259,10 +6046,20 @@ "node": ">=14.17" } }, + "node_modules/@nestjs/cli/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, "node_modules/@nestjs/cli/node_modules/webpack": { - "version": "5.87.0", + "version": "5.89.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz", + "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==", "dev": true, - "license": "MIT", "dependencies": { "@types/eslint-scope": "^3.7.3", "@types/estree": "^1.0.0", @@ -5305,12 +6102,40 @@ } } }, + "node_modules/@nestjs/cli/node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/@nestjs/cli/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/@nestjs/common": { - "version": "10.0.2", - "license": "MIT", + "version": "10.2.10", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.2.10.tgz", + "integrity": "sha512-fwAk931rjW8CNH2Mgwawq/7HWHH1dxkOLdcgs7U52ddLk8CtHXjejm1cbNahewlSbNhvlOl7y1STLHutE6sUqw==", "dependencies": { "iterare": "1.2.1", - "tslib": "2.5.3", + "tslib": "2.6.2", "uid": "2.0.2" }, "funding": { @@ -5332,16 +6157,22 @@ } } }, + "node_modules/@nestjs/common/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, "node_modules/@nestjs/core": { - "version": "10.0.2", + "version": "10.2.10", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.2.10.tgz", + "integrity": "sha512-+ckOI6BPi2ZMHikT9MCG4ctHDc4OnjhoIytrn7f2AYMMXI4bnutJhqyQKc30VDka5x3Wq6QAD57pgSP7y+JjJg==", "hasInstallScript": true, - "license": "MIT", "dependencies": { "@nuxtjs/opencollective": "0.3.2", "fast-safe-stringify": "2.1.1", "iterare": "1.2.1", "path-to-regexp": "3.2.0", - "tslib": "2.5.3", + "tslib": "2.6.2", "uid": "2.0.2" }, "funding": { @@ -5372,15 +6203,21 @@ "version": "3.2.0", "license": "MIT" }, + "node_modules/@nestjs/core/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, "node_modules/@nestjs/platform-express": { - "version": "10.0.2", - "license": "MIT", + "version": "10.2.10", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.2.10.tgz", + "integrity": "sha512-U4KDgtMjH8TqEvt0RzC/POP8ABvL9bYoCScvlGtFSKgVGaMLBKkZ4+jHtbQx6qItYSlBBRUuz/dveMZCObfrkQ==", "dependencies": { "body-parser": "1.20.2", "cors": "2.8.5", "express": "4.18.2", "multer": "1.4.4-lts.1", - "tslib": "2.5.3" + "tslib": "2.6.2" }, "funding": { "type": "opencollective", @@ -5437,13 +6274,19 @@ "node": ">= 0.8" } }, + "node_modules/@nestjs/platform-express/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + }, "node_modules/@nestjs/schematics": { - "version": "10.0.1", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.0.3.tgz", + "integrity": "sha512-2BRujK0GqGQ7j1Zpz+obVfskDnnOeVKt5aXoSaVngKo8Oczy8uYCY+R547TQB+Kf35epdfFER2pVnQrX3/It5A==", "dev": true, - "license": "MIT", "dependencies": { - "@angular-devkit/core": "16.1.0", - "@angular-devkit/schematics": "16.1.0", + "@angular-devkit/core": "16.2.8", + "@angular-devkit/schematics": "16.2.8", "comment-json": "4.2.3", "jsonc-parser": "3.2.0", "pluralize": "8.0.0" @@ -5452,12 +6295,151 @@ "typescript": ">=4.8.2" } }, + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/core": { + "version": "16.2.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.8.tgz", + "integrity": "sha512-PTGozYvh1Bin5lB15PwcXa26Ayd17bWGLS3H8Rs0s+04mUDvfNofmweaX1LgumWWy3nCUTDuwHxX10M3G0wE2g==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "2.3.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + }, + "peerDependencies": { + "chokidar": "^3.5.2" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@nestjs/schematics/node_modules/@angular-devkit/schematics": { + "version": "16.2.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.2.8.tgz", + "integrity": "sha512-MBiKZOlR9/YMdflALr7/7w/BGAfo/BGTrlkqsIB6rDWV1dYiCgxI+033HsiNssLS6RQyCFx/e7JA2aBBzu9zEg==", + "dev": true, + "dependencies": { + "@angular-devkit/core": "16.2.8", + "jsonc-parser": "3.2.0", + "magic-string": "0.30.1", + "ora": "5.4.1", + "rxjs": "7.8.1" + }, + "engines": { + "node": "^16.14.0 || >=18.10.0", + "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", + "yarn": ">= 1.13.0" + } + }, + "node_modules/@nestjs/schematics/node_modules/@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "node_modules/@nestjs/schematics/node_modules/ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@nestjs/schematics/node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/@nestjs/schematics/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "node_modules/@nestjs/schematics/node_modules/jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "node_modules/@nestjs/schematics/node_modules/magic-string": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", + "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", + "dev": true, + "dependencies": { + "@jridgewell/sourcemap-codec": "^1.4.15" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@nestjs/schematics/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/@nestjs/schematics/node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@nestjs/schematics/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, "node_modules/@nestjs/testing": { - "version": "10.0.2", + "version": "10.2.10", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.2.10.tgz", + "integrity": "sha512-IVLUnPz/+fkBtPATYfqTIP+phN9yjkXejmj+JyhmcfPJZpxBmD1i9VSMqa4u54l37j0xkGPscQ0IXpbhqMYUKw==", "dev": true, - "license": "MIT", "dependencies": { - "tslib": "2.5.3" + "tslib": "2.6.2" }, "funding": { "type": "opencollective", @@ -5478,6 +6460,12 @@ } } }, + "node_modules/@nestjs/testing/node_modules/tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + }, "node_modules/@noble/ed25519": { "version": "1.7.1", "funding": [ @@ -6519,11 +7507,6 @@ "npm": ">=7.0.0" } }, - "node_modules/@types/parse-json": { - "version": "4.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/@types/prettier": { "version": "2.7.1", "dev": true, @@ -6894,42 +7877,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "dev": true, - "license": "MIT", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.12.0", - "dev": true, - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "dev": true, - "license": "MIT" - }, "node_modules/ajv-keywords": { "version": "3.5.2", "license": "MIT", @@ -6944,14 +7891,6 @@ "string-width": "^4.1.0" } }, - "node_modules/ansi-colors": { - "version": "4.1.3", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/ansi-escapes": { "version": "4.3.2", "dev": true, @@ -7957,11 +8896,6 @@ "node": ">=10" } }, - "node_modules/chardet": { - "version": "0.7.0", - "dev": true, - "license": "MIT" - }, "node_modules/chokidar": { "version": "3.5.3", "dev": true, @@ -8123,14 +9057,6 @@ "@colors/colors": "1.5.0" } }, - "node_modules/cli-width": { - "version": "3.0.0", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 10" - } - }, "node_modules/cliui": { "version": "8.0.1", "license": "ISC", @@ -8440,38 +9366,6 @@ "node": ">= 0.4.0" } }, - "node_modules/cosmiconfig": { - "version": "7.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/cosmiconfig/node_modules/parse-json": { - "version": "5.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/create-hash": { "version": "1.2.0", "license": "MIT", @@ -9851,30 +10745,6 @@ "license": "MIT", "optional": true }, - "node_modules/external-editor": { - "version": "3.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/external-editor/node_modules/tmp": { - "version": "0.0.33", - "dev": true, - "license": "MIT", - "dependencies": { - "os-tmpdir": "~1.0.2" - }, - "engines": { - "node": ">=0.6.0" - } - }, "node_modules/extract-zip": { "version": "1.7.0", "license": "BSD-2-Clause", @@ -10038,20 +10908,6 @@ "webidl-conversions": "^4.0.2" } }, - "node_modules/figures": { - "version": "3.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "escape-string-regexp": "^1.0.5" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/file-type": { "version": "18.2.0", "license": "MIT", @@ -10177,132 +11033,6 @@ "node": "*" } }, - "node_modules/fork-ts-checker-webpack-plugin": { - "version": "8.0.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/code-frame": "^7.16.7", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "cosmiconfig": "^7.0.1", - "deepmerge": "^4.2.2", - "fs-extra": "^10.0.0", - "memfs": "^3.4.1", - "minimatch": "^3.0.4", - "node-abort-controller": "^3.0.1", - "schema-utils": "^3.1.1", - "semver": "^7.3.5", - "tapable": "^2.2.1" - }, - "engines": { - "node": ">=12.13.0", - "yarn": ">=1.0.0" - }, - "peerDependencies": { - "typescript": ">3.6.0", - "webpack": "^5.11.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/@babel/code-frame": { - "version": "7.22.5", - "dev": true, - "license": "MIT", - "dependencies": { - "@babel/highlight": "^7.22.5" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/fs-extra": { - "version": "10.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/jsonfile": { - "version": "6.1.0", - "dev": true, - "license": "MIT", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/fork-ts-checker-webpack-plugin/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/form-data": { "version": "3.0.0", "dev": true, @@ -10394,11 +11124,6 @@ "node": ">=8" } }, - "node_modules/fs-monkey": { - "version": "1.0.4", - "dev": true, - "license": "Unlicense" - }, "node_modules/fs.realpath": { "version": "1.0.0", "license": "ISC" @@ -10926,21 +11651,6 @@ "node": ">=12.0.0" } }, - "node_modules/import-fresh": { - "version": "3.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/import-lazy": { "version": "4.0.0", "license": "MIT", @@ -11049,95 +11759,6 @@ "version": "1.3.8", "license": "ISC" }, - "node_modules/inquirer": { - "version": "8.2.5", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/inquirer/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/inquirer/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/inquirer/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/inquirer/node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/inquirer/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/interface-blockstore": { "version": "4.0.1", "license": "Apache-2.0 OR MIT", @@ -16311,11 +16932,6 @@ "license": "ISC", "optional": true }, - "node_modules/jsonc-parser": { - "version": "3.2.0", - "dev": true, - "license": "MIT" - }, "node_modules/jsondiffpatch": { "version": "0.4.1", "license": "MIT", @@ -17095,17 +17711,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/magic-string": { - "version": "0.30.0", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.13" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/make-dir": { "version": "3.1.0", "license": "MIT", @@ -17154,17 +17759,6 @@ "node": ">= 0.6" } }, - "node_modules/memfs": { - "version": "3.5.3", - "dev": true, - "license": "Unlicense", - "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" - } - }, "node_modules/merge-descriptors": { "version": "1.0.1", "license": "MIT" @@ -17491,11 +18085,6 @@ "node": ">=8.0.0" } }, - "node_modules/mute-stream": { - "version": "0.0.8", - "dev": true, - "license": "ISC" - }, "node_modules/nan": { "version": "2.17.0", "license": "MIT" @@ -17571,11 +18160,6 @@ "tslib": "^2.0.3" } }, - "node_modules/node-abort-controller": { - "version": "3.1.1", - "dev": true, - "license": "MIT" - }, "node_modules/node-addon-api": { "version": "2.0.2", "license": "MIT" @@ -18481,14 +19065,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/os-tmpdir": { - "version": "1.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/p-defer": { "version": "3.0.0", "license": "MIT", @@ -18891,17 +19467,6 @@ "tslib": "^2.0.3" } }, - "node_modules/parent-module": { - "version": "1.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/parse-duration": { "version": "1.0.2", "license": "MIT" @@ -18962,50 +19527,11 @@ "version": "1.0.7", "license": "MIT" }, - "node_modules/path-scurry": { - "version": "1.9.2", - "dev": true, - "license": "BlueOak-1.0.0", - "dependencies": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" - }, - "engines": { - "node": ">=16 || 14 >=14.17" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "9.1.2", - "dev": true, - "license": "ISC", - "engines": { - "node": "14 || >=16.14" - } - }, - "node_modules/path-scurry/node_modules/minipass": { - "version": "6.0.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/path-to-regexp": { "version": "2.4.0", "dev": true, "license": "MIT" }, - "node_modules/path-type": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, "node_modules/peek-readable": { "version": "5.0.0", "license": "MIT", @@ -19877,14 +20403,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/requires-port": { "version": "1.0.0", "license": "MIT" @@ -19923,14 +20441,6 @@ "node": ">=8" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=4" - } - }, "node_modules/resolve.exports": { "version": "1.1.0", "license": "MIT", @@ -20021,14 +20531,6 @@ "rsa-unpack": "bin/cmd.js" } }, - "node_modules/run-async": { - "version": "2.4.1", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.12.0" - } - }, "node_modules/run-parallel-limit": { "version": "1.1.0", "funding": [ @@ -20787,14 +21289,6 @@ "node": ">=4" } }, - "node_modules/symbol-observable": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=0.10" - } - }, "node_modules/tapable": { "version": "2.2.1", "license": "MIT", @@ -20979,11 +21473,6 @@ "license": "MIT", "optional": true }, - "node_modules/through": { - "version": "2.3.8", - "dev": true, - "license": "MIT" - }, "node_modules/through2": { "version": "2.0.5", "license": "MIT", @@ -21541,107 +22030,6 @@ "node": ">=0.4.0" } }, - "node_modules/tsconfig-paths-webpack-plugin": { - "version": "4.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.7.0", - "tsconfig-paths": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/ansi-styles": { - "version": "4.3.0", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/chalk": { - "version": "4.1.2", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/color-convert": { - "version": "2.0.1", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/color-name": { - "version": "1.1.4", - "dev": true, - "license": "MIT" - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/has-flag": { - "version": "4.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/json5": { - "version": "2.2.3", - "dev": true, - "license": "MIT", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/supports-color": { - "version": "7.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/tsconfig-paths": { - "version": "4.2.0", - "dev": true, - "license": "MIT", - "dependencies": { - "json5": "^2.2.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/tslib": { "version": "2.5.3", "license": "0BSD" @@ -21844,14 +22232,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/universalify": { - "version": "2.0.0", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 10.0.0" - } - }, "node_modules/unpipe": { "version": "1.0.0", "license": "MIT", @@ -22607,14 +22987,6 @@ "version": "4.0.0", "license": "ISC" }, - "node_modules/yaml": { - "version": "1.10.2", - "dev": true, - "license": "ISC", - "engines": { - "node": ">= 6" - } - }, "node_modules/yargs": { "version": "17.6.2", "license": "MIT", @@ -22714,124 +23086,6 @@ } } }, - "@angular-devkit/core": { - "version": "16.1.0", - "dev": true, - "requires": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.0", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "dependencies": { - "ajv": { - "version": "8.12.0", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "dev": true - }, - "source-map": { - "version": "0.7.4", - "dev": true - } - } - }, - "@angular-devkit/schematics": { - "version": "16.1.0", - "dev": true, - "requires": { - "@angular-devkit/core": "16.1.0", - "jsonc-parser": "3.2.0", - "magic-string": "0.30.0", - "ora": "5.4.1", - "rxjs": "7.8.1" - } - }, - "@angular-devkit/schematics-cli": { - "version": "16.1.0", - "dev": true, - "requires": { - "@angular-devkit/core": "16.1.0", - "@angular-devkit/schematics": "16.1.0", - "ansi-colors": "4.1.3", - "inquirer": "8.2.4", - "symbol-observable": "4.0.0", - "yargs-parser": "21.1.1" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "dev": true - }, - "inquirer": { - "version": "8.2.4", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "yargs-parser": { - "version": "21.1.1", - "dev": true - } - } - }, "@assemblyscript/loader": { "version": "0.9.4" }, @@ -25725,19 +25979,22 @@ } }, "@nestjs/cli": { - "version": "10.0.3", + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/@nestjs/cli/-/cli-10.2.1.tgz", + "integrity": "sha512-CAJAQwmxFZfB3RTvqz/eaXXWpyU+mZ4QSqfBYzjneTsPgF+uyOAW3yQpaLNn9Dfcv39R9UxSuAhayv6yuFd+Jg==", "dev": true, "requires": { - "@angular-devkit/core": "16.1.0", - "@angular-devkit/schematics": "16.1.0", - "@angular-devkit/schematics-cli": "16.1.0", + "@angular-devkit/core": "16.2.8", + "@angular-devkit/schematics": "16.2.8", + "@angular-devkit/schematics-cli": "16.2.8", "@nestjs/schematics": "^10.0.1", "chalk": "4.1.2", "chokidar": "3.5.3", "cli-table3": "0.6.3", "commander": "4.1.1", - "fork-ts-checker-webpack-plugin": "8.0.0", - "inquirer": "8.2.5", + "fork-ts-checker-webpack-plugin": "9.0.2", + "glob": "10.3.10", + "inquirer": "8.2.6", "node-emoji": "1.11.0", "ora": "5.4.1", "os-name": "4.0.1", @@ -25746,18 +26003,297 @@ "source-map-support": "0.5.21", "tree-kill": "1.2.2", "tsconfig-paths": "4.2.0", - "tsconfig-paths-webpack-plugin": "4.0.1", - "typescript": "5.1.3", - "webpack": "5.87.0", + "tsconfig-paths-webpack-plugin": "4.1.0", + "typescript": "5.2.2", + "webpack": "5.89.0", "webpack-node-externals": "3.0.0" }, "dependencies": { + "@angular-devkit/core": { + "version": "16.2.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.8.tgz", + "integrity": "sha512-PTGozYvh1Bin5lB15PwcXa26Ayd17bWGLS3H8Rs0s+04mUDvfNofmweaX1LgumWWy3nCUTDuwHxX10M3G0wE2g==", + "dev": true, + "requires": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "2.3.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + } + }, + "@angular-devkit/schematics": { + "version": "16.2.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.2.8.tgz", + "integrity": "sha512-MBiKZOlR9/YMdflALr7/7w/BGAfo/BGTrlkqsIB6rDWV1dYiCgxI+033HsiNssLS6RQyCFx/e7JA2aBBzu9zEg==", + "dev": true, + "requires": { + "@angular-devkit/core": "16.2.8", + "jsonc-parser": "3.2.0", + "magic-string": "0.30.1", + "ora": "5.4.1", + "rxjs": "7.8.1" + } + }, + "@angular-devkit/schematics-cli": { + "version": "16.2.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics-cli/-/schematics-cli-16.2.8.tgz", + "integrity": "sha512-EXURJCzWTVYCipiTT4vxQQOrF63asOUDbeOy3OtiSh7EwIUvxm3BPG6hquJqngEnI/N6bA75NJ1fBhU6Hrh7eA==", + "dev": true, + "requires": { + "@angular-devkit/core": "16.2.8", + "@angular-devkit/schematics": "16.2.8", + "ansi-colors": "4.1.3", + "inquirer": "8.2.4", + "symbol-observable": "4.0.0", + "yargs-parser": "21.1.1" + }, + "dependencies": { + "inquirer": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.4.tgz", + "integrity": "sha512-nn4F01dxU8VeKfq192IjLsxu0/OmMZ4Lg3xKAns148rCaXP6ntAoEkVYZThWjwON8AlzdZZi6oqnhNbxUG9hVg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^7.0.0" + } + } + } + }, + "@babel/code-frame": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.23.4.tgz", + "integrity": "sha512-r1IONyb6Ia+jYR2vvIDhdWdlTGhqbBoFqLTQidzZ4kepUFH15ejXvFHxCVbtl7BOXIudsIubf4E81xeA3h3IXA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.23.4", + "chalk": "^2.4.2" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/helper-validator-identifier": { + "version": "7.22.20", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.22.20.tgz", + "integrity": "sha512-Y4OZ+ytlatR8AI+8KZfKuL5urKp7qey08ha31L8b3BwewJAoJamTzyvxPR/5D+KkdJCGPq/+8TukHBlY10FX9A==", + "dev": true + }, + "@babel/highlight": { + "version": "7.23.4", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.23.4.tgz", + "integrity": "sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.22.20", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, "@types/estree": { - "version": "1.0.1", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", "dev": true }, "@webassemblyjs/ast": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", "dev": true, "requires": { "@webassemblyjs/helper-numbers": "1.11.6", @@ -25766,18 +26302,26 @@ }, "@webassemblyjs/floating-point-hex-parser": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", "dev": true }, "@webassemblyjs/helper-api-error": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", "dev": true }, "@webassemblyjs/helper-buffer": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", "dev": true }, "@webassemblyjs/helper-numbers": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", "dev": true, "requires": { "@webassemblyjs/floating-point-hex-parser": "1.11.6", @@ -25787,10 +26331,14 @@ }, "@webassemblyjs/helper-wasm-bytecode": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", "dev": true }, "@webassemblyjs/helper-wasm-section": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", "dev": true, "requires": { "@webassemblyjs/ast": "1.11.6", @@ -25801,6 +26349,8 @@ }, "@webassemblyjs/ieee754": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", "dev": true, "requires": { "@xtuc/ieee754": "^1.2.0" @@ -25808,6 +26358,8 @@ }, "@webassemblyjs/leb128": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", "dev": true, "requires": { "@xtuc/long": "4.2.2" @@ -25815,10 +26367,14 @@ }, "@webassemblyjs/utf8": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", "dev": true }, "@webassemblyjs/wasm-edit": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", "dev": true, "requires": { "@webassemblyjs/ast": "1.11.6", @@ -25833,6 +26389,8 @@ }, "@webassemblyjs/wasm-gen": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", "dev": true, "requires": { "@webassemblyjs/ast": "1.11.6", @@ -25844,6 +26402,8 @@ }, "@webassemblyjs/wasm-opt": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", "dev": true, "requires": { "@webassemblyjs/ast": "1.11.6", @@ -25854,6 +26414,8 @@ }, "@webassemblyjs/wasm-parser": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", "dev": true, "requires": { "@webassemblyjs/ast": "1.11.6", @@ -25866,6 +26428,8 @@ }, "@webassemblyjs/wast-printer": { "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", "dev": true, "requires": { "@webassemblyjs/ast": "1.11.6", @@ -25873,14 +26437,45 @@ } }, "acorn": { - "version": "8.9.0", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.11.2.tgz", + "integrity": "sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==", "dev": true }, "acorn-import-assertions": { "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", "dev": true, "requires": {} }, + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + } + }, + "ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "dev": true + }, "ansi-styles": { "version": "4.3.0", "dev": true, @@ -25888,8 +26483,16 @@ "color-convert": "^2.0.1" } }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, "brace-expansion": { "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", "dev": true, "requires": { "balanced-match": "^1.0.0" @@ -25903,6 +26506,18 @@ "supports-color": "^7.1.0" } }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "cli-width": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz", + "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==", + "dev": true + }, "color-convert": { "version": "2.0.1", "dev": true, @@ -25918,40 +26533,385 @@ "version": "4.1.1", "dev": true }, + "cosmiconfig": { + "version": "8.3.6", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz", + "integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==", + "dev": true, + "requires": { + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0", + "path-type": "^4.0.0" + } + }, "es-module-lexer": { - "version": "1.3.0", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.4.1.tgz", + "integrity": "sha512-cXLGjP0c4T3flZJKQSuziYoq7MlT+rnvfZjfp7h+I7K9BNX54kP9nyWvdbwjQ4u1iWbOL4u96fgeZLToQlZC7w==", + "dev": true + }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "figures": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + } + }, + "fork-ts-checker-webpack-plugin": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-9.0.2.tgz", + "integrity": "sha512-Uochze2R8peoN1XqlSi/rGUkDQpRogtLFocP9+PGu68zk1BDAKXfdeCdyVZpgTk8V8WFVQXdEz426VKjXLO1Gg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.16.7", + "chalk": "^4.1.2", + "chokidar": "^3.5.3", + "cosmiconfig": "^8.2.0", + "deepmerge": "^4.2.2", + "fs-extra": "^10.0.0", + "memfs": "^3.4.1", + "minimatch": "^3.0.4", + "node-abort-controller": "^3.0.1", + "schema-utils": "^3.1.1", + "semver": "^7.3.5", + "tapable": "^2.2.1" + } + }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "fs-monkey": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.5.tgz", + "integrity": "sha512-8uMbBjrhzW76TYgEV27Y5E//W2f/lTFmx78P2w19FZSxarhI/798APGQyuGCwmkNxgwGRhrLfvWyLBvNtuOmew==", "dev": true }, "glob": { - "version": "9.3.5", + "version": "10.3.10", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.10.tgz", + "integrity": "sha512-fa46+tv1Ak0UPK1TOy/pZrIybNNt4HCv7SDzwyfiOZkvZLEbjsZkJBPtDHVshZjbecAoAGSC20MjLDG/qr679g==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "minimatch": "^8.0.2", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" + "foreground-child": "^3.1.0", + "jackspeak": "^2.3.5", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "dependencies": { + "minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } } }, "has-flag": { "version": "4.0.0", "dev": true }, + "import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "inquirer": { + "version": "8.2.6", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz", + "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^4.1.1", + "cli-cursor": "^3.1.0", + "cli-width": "^3.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.21", + "mute-stream": "0.0.8", + "ora": "^5.4.1", + "run-async": "^2.4.0", + "rxjs": "^7.5.5", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", + "through": "^2.3.6", + "wrap-ansi": "^6.0.1" + }, + "dependencies": { + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, "json5": { "version": "2.2.3", "dev": true }, - "minimatch": { - "version": "8.0.4", + "jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", "dev": true, "requires": { - "brace-expansion": "^2.0.1" + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "lru-cache": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", + "dev": true + }, + "magic-string": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", + "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dev": true, + "requires": { + "fs-monkey": "^1.0.4" } }, + "minipass": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", + "dev": true + }, + "mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "dev": true + }, + "node-abort-controller": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/node-abort-controller/-/node-abort-controller-3.1.1.tgz", + "integrity": "sha512-AGK2yQKIjRuqnc6VkX2Xj5d+QW8xZ87pa1UK6yA6ouUyuxfHuMP6umE5QK7UmTeOAymo+Zx1Fxiuw9rVx8taHQ==", + "dev": true + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" + } + }, + "path-scurry": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", + "dev": true, + "requires": { + "lru-cache": "^9.1.1 || ^10.0.0", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" + } + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, "rimraf": { "version": "4.4.1", "dev": true, "requires": { "glob": "^9.2.0" + }, + "dependencies": { + "glob": { + "version": "9.3.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.5.tgz", + "integrity": "sha512-e1LleDykUz2Iu+MTYdkSsuWX8lvAjAcs0Xef0lNIu0S2wOAzuTxCJtcd9S3cijlwYF18EsU3rzb8jPVobxDh9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "minimatch": "^8.0.2", + "minipass": "^4.2.4", + "path-scurry": "^1.6.1" + } + }, + "minimatch": { + "version": "8.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-8.0.4.tgz", + "integrity": "sha512-W0Wvr9HyFXZRGIDgCicunpQ299OKXs9RgZfaukz4qAW/pJhcpUfupc9c+OObPOFueNy8VSrZgEmDtk6Kh4WzDA==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minipass": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", + "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "dev": true + } + } + }, + "run-async": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true + }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true + }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" } }, "supports-color": { @@ -25961,6 +26921,27 @@ "has-flag": "^4.0.0" } }, + "symbol-observable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-4.0.0.tgz", + "integrity": "sha512-b19dMThMV4HVFynSAM1++gBHAbk2Tc/osgLIBZMKsyqh34jb2e8Os7T6ZW/Bt3pJFdBTd2JwAnAAEQV7rSNvcQ==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "tsconfig-paths": { "version": "4.2.0", "dev": true, @@ -25970,12 +26951,33 @@ "strip-bom": "^3.0.0" } }, + "tsconfig-paths-webpack-plugin": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.1.0.tgz", + "integrity": "sha512-xWFISjviPydmtmgeUAuXp4N1fky+VCtfhOkDUFIv5ea7p4wuTomI4QTrXvFBX2S4jZsmyTSrStQl+E+4w+RzxA==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.7.0", + "tsconfig-paths": "^4.1.2" + } + }, "typescript": { - "version": "5.1.3", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz", + "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==", + "dev": true + }, + "universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", "dev": true }, "webpack": { - "version": "5.87.0", + "version": "5.89.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.89.0.tgz", + "integrity": "sha512-qyfIC10pOr70V+jkmud8tMfajraGCZMBWJtrmuBymQKCrLTRejBI8STDp1MCyZu/QTdZSeacCQYpYNQVOzX5kw==", "dev": true, "requires": { "@types/eslint-scope": "^3.7.3", @@ -26003,41 +27005,76 @@ "watchpack": "^2.4.0", "webpack-sources": "^3.2.3" } + }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true } } }, "@nestjs/common": { - "version": "10.0.2", + "version": "10.2.10", + "resolved": "https://registry.npmjs.org/@nestjs/common/-/common-10.2.10.tgz", + "integrity": "sha512-fwAk931rjW8CNH2Mgwawq/7HWHH1dxkOLdcgs7U52ddLk8CtHXjejm1cbNahewlSbNhvlOl7y1STLHutE6sUqw==", "requires": { "iterare": "1.2.1", - "tslib": "2.5.3", + "tslib": "2.6.2", "uid": "2.0.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" + } } }, "@nestjs/core": { - "version": "10.0.2", + "version": "10.2.10", + "resolved": "https://registry.npmjs.org/@nestjs/core/-/core-10.2.10.tgz", + "integrity": "sha512-+ckOI6BPi2ZMHikT9MCG4ctHDc4OnjhoIytrn7f2AYMMXI4bnutJhqyQKc30VDka5x3Wq6QAD57pgSP7y+JjJg==", "requires": { "@nuxtjs/opencollective": "0.3.2", "fast-safe-stringify": "2.1.1", "iterare": "1.2.1", "path-to-regexp": "3.2.0", - "tslib": "2.5.3", + "tslib": "2.6.2", "uid": "2.0.2" }, "dependencies": { "path-to-regexp": { "version": "3.2.0" + }, + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" } } }, "@nestjs/platform-express": { - "version": "10.0.2", + "version": "10.2.10", + "resolved": "https://registry.npmjs.org/@nestjs/platform-express/-/platform-express-10.2.10.tgz", + "integrity": "sha512-U4KDgtMjH8TqEvt0RzC/POP8ABvL9bYoCScvlGtFSKgVGaMLBKkZ4+jHtbQx6qItYSlBBRUuz/dveMZCObfrkQ==", "requires": { "body-parser": "1.20.2", "cors": "2.8.5", "express": "4.18.2", "multer": "1.4.4-lts.1", - "tslib": "2.5.3" + "tslib": "2.6.2" }, "dependencies": { "body-parser": { @@ -26074,25 +27111,137 @@ "iconv-lite": "0.4.24", "unpipe": "1.0.0" } + }, + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" } } }, "@nestjs/schematics": { - "version": "10.0.1", + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/@nestjs/schematics/-/schematics-10.0.3.tgz", + "integrity": "sha512-2BRujK0GqGQ7j1Zpz+obVfskDnnOeVKt5aXoSaVngKo8Oczy8uYCY+R547TQB+Kf35epdfFER2pVnQrX3/It5A==", "dev": true, "requires": { - "@angular-devkit/core": "16.1.0", - "@angular-devkit/schematics": "16.1.0", + "@angular-devkit/core": "16.2.8", + "@angular-devkit/schematics": "16.2.8", "comment-json": "4.2.3", "jsonc-parser": "3.2.0", "pluralize": "8.0.0" + }, + "dependencies": { + "@angular-devkit/core": { + "version": "16.2.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.8.tgz", + "integrity": "sha512-PTGozYvh1Bin5lB15PwcXa26Ayd17bWGLS3H8Rs0s+04mUDvfNofmweaX1LgumWWy3nCUTDuwHxX10M3G0wE2g==", + "dev": true, + "requires": { + "ajv": "8.12.0", + "ajv-formats": "2.1.1", + "jsonc-parser": "3.2.0", + "picomatch": "2.3.1", + "rxjs": "7.8.1", + "source-map": "0.7.4" + } + }, + "@angular-devkit/schematics": { + "version": "16.2.8", + "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.2.8.tgz", + "integrity": "sha512-MBiKZOlR9/YMdflALr7/7w/BGAfo/BGTrlkqsIB6rDWV1dYiCgxI+033HsiNssLS6RQyCFx/e7JA2aBBzu9zEg==", + "dev": true, + "requires": { + "@angular-devkit/core": "16.2.8", + "jsonc-parser": "3.2.0", + "magic-string": "0.30.1", + "ora": "5.4.1", + "rxjs": "7.8.1" + } + }, + "@jridgewell/sourcemap-codec": { + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true + }, + "ajv": { + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.12.0.tgz", + "integrity": "sha512-sRu1kpcO9yLtYxBKvqfTeh9KzZEwO3STyX1HT+4CaDzC6HpTGYhIhPIzj9XuKU7KYDwnaeh5hcOwjy1QuJzBPA==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dev": true, + "requires": { + "ajv": "^8.0.0" + } + }, + "json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true + }, + "jsonc-parser": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", + "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", + "dev": true + }, + "magic-string": { + "version": "0.30.1", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", + "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", + "dev": true, + "requires": { + "@jridgewell/sourcemap-codec": "^1.4.15" + } + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true + }, + "require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "dev": true + }, + "source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true + } } }, "@nestjs/testing": { - "version": "10.0.2", + "version": "10.2.10", + "resolved": "https://registry.npmjs.org/@nestjs/testing/-/testing-10.2.10.tgz", + "integrity": "sha512-IVLUnPz/+fkBtPATYfqTIP+phN9yjkXejmj+JyhmcfPJZpxBmD1i9VSMqa4u54l37j0xkGPscQ0IXpbhqMYUKw==", "dev": true, "requires": { - "tslib": "2.5.3" + "tslib": "2.6.2" + }, + "dependencies": { + "tslib": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", + "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", + "dev": true + } } }, "@noble/ed25519": { @@ -26885,10 +28034,6 @@ } } }, - "@types/parse-json": { - "version": "4.0.0", - "dev": true - }, "@types/prettier": { "version": "2.7.1", "dev": true @@ -27164,29 +28309,6 @@ "uri-js": "^4.2.2" } }, - "ajv-formats": { - "version": "2.1.1", - "dev": true, - "requires": { - "ajv": "^8.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.12.0", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "dev": true - } - } - }, "ajv-keywords": { "version": "3.5.2", "requires": {} @@ -27197,10 +28319,6 @@ "string-width": "^4.1.0" } }, - "ansi-colors": { - "version": "4.1.3", - "dev": true - }, "ansi-escapes": { "version": "4.3.2", "dev": true, @@ -27841,10 +28959,6 @@ "version": "1.0.2", "dev": true }, - "chardet": { - "version": "0.7.0", - "dev": true - }, "chokidar": { "version": "3.5.3", "dev": true, @@ -27939,10 +29053,6 @@ "string-width": "^4.2.0" } }, - "cli-width": { - "version": "3.0.0", - "dev": true - }, "cliui": { "version": "8.0.1", "requires": { @@ -28147,29 +29257,6 @@ "corser": { "version": "2.0.1" }, - "cosmiconfig": { - "version": "7.1.0", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - }, - "dependencies": { - "parse-json": { - "version": "5.2.0", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - } - } - }, "create-hash": { "version": "1.2.0", "requires": { @@ -29097,24 +30184,6 @@ "version": "3.0.2", "optional": true }, - "external-editor": { - "version": "3.1.0", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "dependencies": { - "tmp": { - "version": "0.0.33", - "dev": true, - "requires": { - "os-tmpdir": "~1.0.2" - } - } - } - }, "extract-zip": { "version": "1.7.0", "optional": true, @@ -29222,13 +30291,6 @@ "fetch-mock": "^9.11.0" } }, - "figures": { - "version": "3.2.0", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, "file-type": { "version": "18.2.0", "requires": { @@ -29308,87 +30370,6 @@ "version": "0.6.1", "optional": true }, - "fork-ts-checker-webpack-plugin": { - "version": "8.0.0", - "dev": true, - "requires": { - "@babel/code-frame": "^7.16.7", - "chalk": "^4.1.2", - "chokidar": "^3.5.3", - "cosmiconfig": "^7.0.1", - "deepmerge": "^4.2.2", - "fs-extra": "^10.0.0", - "memfs": "^3.4.1", - "minimatch": "^3.0.4", - "node-abort-controller": "^3.0.1", - "schema-utils": "^3.1.1", - "semver": "^7.3.5", - "tapable": "^2.2.1" - }, - "dependencies": { - "@babel/code-frame": { - "version": "7.22.5", - "dev": true, - "requires": { - "@babel/highlight": "^7.22.5" - } - }, - "ansi-styles": { - "version": "4.3.0", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "dev": true - }, - "fs-extra": { - "version": "10.1.0", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "has-flag": { - "version": "4.0.0", - "dev": true - }, - "jsonfile": { - "version": "6.1.0", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "supports-color": { - "version": "7.2.0", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "form-data": { "version": "3.0.0", "dev": true, @@ -29450,10 +30431,6 @@ } } }, - "fs-monkey": { - "version": "1.0.4", - "dev": true - }, "fs.realpath": { "version": "1.0.0" }, @@ -29762,14 +30739,6 @@ "queue": "6.0.2" } }, - "import-fresh": { - "version": "3.3.0", - "dev": true, - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, "import-lazy": { "version": "4.0.0" }, @@ -29835,66 +30804,6 @@ "ini": { "version": "1.3.8" }, - "inquirer": { - "version": "8.2.5", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "chalk": "^4.1.1", - "cli-cursor": "^3.1.0", - "cli-width": "^3.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.21", - "mute-stream": "0.0.8", - "ora": "^5.4.1", - "run-async": "^2.4.0", - "rxjs": "^7.5.5", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0", - "through": "^2.3.6", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "interface-blockstore": { "version": "4.0.1", "requires": { @@ -33137,10 +34046,6 @@ "version": "5.0.1", "optional": true }, - "jsonc-parser": { - "version": "3.2.0", - "dev": true - }, "jsondiffpatch": { "version": "0.4.1", "requires": { @@ -33650,13 +34555,6 @@ "version": "2.5.1", "dev": true }, - "magic-string": { - "version": "0.30.0", - "dev": true, - "requires": { - "@jridgewell/sourcemap-codec": "^1.4.13" - } - }, "make-dir": { "version": "3.1.0", "requires": { @@ -33689,13 +34587,6 @@ "media-typer": { "version": "0.3.0" }, - "memfs": { - "version": "3.5.3", - "dev": true, - "requires": { - "fs-monkey": "^1.0.4" - } - }, "merge-descriptors": { "version": "1.0.1" }, @@ -33888,10 +34779,6 @@ "murmurhash3js-revisited": { "version": "3.0.0" }, - "mute-stream": { - "version": "0.0.8", - "dev": true - }, "nan": { "version": "2.17.0" }, @@ -33939,10 +34826,6 @@ "tslib": "^2.0.3" } }, - "node-abort-controller": { - "version": "3.1.1", - "dev": true - }, "node-addon-api": { "version": "2.0.2" }, @@ -34494,10 +35377,6 @@ "windows-release": "^4.0.0" } }, - "os-tmpdir": { - "version": "1.0.2", - "dev": true - }, "p-defer": { "version": "3.0.0" }, @@ -34706,13 +35585,6 @@ "tslib": "^2.0.3" } }, - "parent-module": { - "version": "1.0.1", - "dev": true, - "requires": { - "callsites": "^3.0.0" - } - }, "parse-duration": { "version": "1.0.2" }, @@ -34752,32 +35624,10 @@ "path-parse": { "version": "1.0.7" }, - "path-scurry": { - "version": "1.9.2", - "dev": true, - "requires": { - "lru-cache": "^9.1.1", - "minipass": "^5.0.0 || ^6.0.2" - }, - "dependencies": { - "lru-cache": { - "version": "9.1.2", - "dev": true - }, - "minipass": { - "version": "6.0.2", - "dev": true - } - } - }, "path-to-regexp": { "version": "2.4.0", "dev": true }, - "path-type": { - "version": "4.0.0", - "dev": true - }, "peek-readable": { "version": "5.0.0" }, @@ -35348,10 +36198,6 @@ "require-directory": { "version": "2.1.1" }, - "require-from-string": { - "version": "2.0.2", - "dev": true - }, "requires-port": { "version": "1.0.0" }, @@ -35378,10 +36224,6 @@ } } }, - "resolve-from": { - "version": "4.0.0", - "dev": true - }, "resolve.exports": { "version": "1.1.0" }, @@ -35439,10 +36281,6 @@ "optimist": "~0.3.5" } }, - "run-async": { - "version": "2.4.1", - "dev": true - }, "run-parallel-limit": { "version": "1.1.0", "requires": { @@ -35942,10 +36780,6 @@ "has-flag": "^3.0.0" } }, - "symbol-observable": { - "version": "4.0.0", - "dev": true - }, "tapable": { "version": "2.2.1" }, @@ -36050,10 +36884,6 @@ "version": "0.0.2", "optional": true }, - "through": { - "version": "2.3.8", - "dev": true - }, "through2": { "version": "2.0.5", "optional": true, @@ -36390,67 +37220,6 @@ } } }, - "tsconfig-paths-webpack-plugin": { - "version": "4.0.1", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.7.0", - "tsconfig-paths": "^4.1.2" - }, - "dependencies": { - "ansi-styles": { - "version": "4.3.0", - "dev": true, - "requires": { - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "4.1.2", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "dev": true - }, - "json5": { - "version": "2.2.3", - "dev": true - }, - "supports-color": { - "version": "7.2.0", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "tsconfig-paths": { - "version": "4.2.0", - "dev": true, - "requires": { - "json5": "^2.2.2", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - } - } - }, "tslib": { "version": "2.5.3" }, @@ -36574,10 +37343,6 @@ "crypto-random-string": "^4.0.0" } }, - "universalify": { - "version": "2.0.0", - "dev": true - }, "unpipe": { "version": "1.0.0" }, @@ -37043,10 +37808,6 @@ "yallist": { "version": "4.0.0" }, - "yaml": { - "version": "1.10.2", - "dev": true - }, "yargs": { "version": "17.6.2", "requires": { diff --git a/packages/backend/package.json b/packages/backend/package.json index 0f5b46f61e..541ab72874 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -1,147 +1,148 @@ { - "name": "@quiet/backend", - "version": "2.0.3-alpha.5", - "description": "tlg-manager", - "types": "lib/index.d.ts", - "type": "module", - "exports": "lib/index.js", - "author": "", - "license": "MIT", - "private": true, - "scripts": { - "build": "tsc -p tsconfig.build.json", - "webpack": "webpack --env mode=development && cp ./lib/bundle.cjs ../backend-bundle/bundle.cjs", - "webpack:prod": "webpack --env mode=production && cp ./lib/bundle.cjs ../backend-bundle/bundle.cjs", - "applyPatches": "patch -f -p0 < ./electron-fetch.patch || true && patch -f -p0 --forward --binary < ./parse-duration.patch || true && patch -f -p0 --forward --binary < ./parse-duration-esm.patch || true", - "prepare": "npm run applyPatches && npm run webpack", - "version": "git add -A src", - "lint": "eslint --ext .jsx,.js,.ts,.tsx ./src/ --fix", - "lint-ci": "eslint --ext .jsx,.js,.ts,.tsx ./src/", - "test-nest": "cross-env NODE_OPTIONS=--experimental-vm-modules DEBUG=ipfs:*,backend:* node_modules/jest/bin/jest.js --detectOpenHandles --forceExit ./src/nest/**/*.spec.ts", - "test": "cross-env NODE_OPTIONS=--experimental-vm-modules DEBUG=ipfs:*,backend:* node_modules/jest/bin/jest.js ./src/**/* --runInBand --verbose --testPathIgnorePatterns=\".src/(!?nodeTest*)|(.node_modules*)\"", - "test-ci": "cross-env NODE_OPTIONS=--experimental-vm-modules jest ./src/**/* --runInBand --colors --ci --silent --verbose --testPathIgnorePatterns=\".src/nest/(!?nodeTest*)|(.node_modules*)|src/nest/.*\\.tor.spec\\.(t|j)s|src/nest/ipfs-file-manager/big-files.long.spec.ts$\"", - "test-ci-tor": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --colors --ci --silent --verbose --detectOpenHandles --forceExit ./src/nest/**/*.tor.spec.ts", - "test-ci-long-running": "cross-env DEBUG=backend:* NODE_OPTIONS=--experimental-vm-modules jest --colors --ci --verbose ./src/nest/**/*.long.spec.ts", - "test-connect": "cross-env NODE_OPTIONS=--experimental-vm-modules DEBUG='libp2p:websockets*' jest ./src/nodeTest/* --verbose", - "test-connect-ci": "cross-env NODE_OPTIONS=--experimental-vm-modules jest ./src/nodeTest/* --colors --ci --silent --verbose", - "test-replication-no-tor": "cross-env NODE_OPTIONS=--experimental-vm-modules ts-node -v && cross-env DEBUG='backend:dbSnap*,backend:localTest*' ts-node src/nodeTest/testReplicate.ts --nodesCount 1 --timeThreshold 200 --entriesCount 1000 --no-useTor", - "test-replication-tor": "cross-env NODE_OPTIONS=--experimental-vm-modules cross-env DEBUG='backend:dbSnap*,backend:localTest*' ts-node src/nodeTest/testReplicate.ts --nodesCount 1 --timeThreshold 500 --entriesCount 1000 --useTor", - "rmDist": "rimraf lib/" - }, - "repository": { - "type": "git", - "url": "git+ssh://git@github.com:TryQuiet/backend.git" - }, - "files": [ - "lib/**/*", - "package-lock.json" - ], - "jest": { - "preset": "ts-jest/presets/default-esm", - "clearMocks": true, - "coverageProvider": "v8", - "transformIgnorePatterns": [ - "node_modules/(?!p-defer|peer-id)" - ], - "testTimeout": 40000, - "setupFiles": [ - "./jestSetup.js" - ], - "testEnvironment": "jest-environment-node" - }, - "devDependencies": { - "@nestjs/cli": "^10.0.0", - "@nestjs/schematics": "^10.0.0", - "@nestjs/testing": "^10.0.0", - "@quiet/eslint-config": "^2.0.2-alpha.0", - "@quiet/state-manager": "^2.0.2-alpha.3", - "@types/crypto-js": "^4.0.2", - "@types/express": "^4.17.9", - "@types/jest": "28.1.8", - "@types/luxon": "^3.3.0", - "@types/mock-fs": "^4.13.1", - "@types/node": "18.11.9", - "@types/node-fetch": "^2.5.11", - "@types/orbit-db": "git+https://github.com/orbitdb/orbit-db-types.git", - "@types/supertest": "^2.0.11", - "@types/tmp": "^0.2.3", - "@types/validator": "^13.11.5", - "@types/ws": "8.5.3", - "babel-jest": "^29.3.1", - "cross-env": "^5.2.0", - "fetch-mock-jest": "^1.5.1", - "jest": "^29.4.2", - "mock-fs": "^5.1.2", - "tmp": "^0.2.1", - "ts-jest": "^29.0.3", - "ts-loader": "9.4.2", - "ts-node": "10.9.1", - "typescript": "^4.9.3", - "wait-for-expect": "^3.0.2", - "webpack": "5.75.0", - "webpack-cli": "5.0.1", - "yargs": "^17.1.0" - }, - "dependencies": { - "@chainsafe/libp2p-gossipsub": "6.1.0", - "@chainsafe/libp2p-noise": "11.0.0", - "@nestjs/common": "^10.0.0", - "@nestjs/core": "^10.0.0", - "@nestjs/platform-express": "^10.0.0", - "@peculiar/webcrypto": "1.4.3", - "@quiet/common": "^2.0.2-alpha.1", - "@quiet/identity": "^2.0.2-alpha.2", - "@quiet/logger": "^2.0.2-alpha.0", - "@quiet/types": "^2.0.2-alpha.1", - "abortable-iterator": "^3.0.0", - "class-transformer": "^0.5.1", - "class-validator": "^0.13.1", - "cli-table": "^0.3.6", - "commander": "^7.2.0", - "cors": "^2.8.5", - "crypto-js": "^4.1.1", - "debug": "^4.3.1", - "dotenv": "8.2.0", - "events": "^3.2.0", - "express": "^4.17.1", - "get-port": "^5.1.1", - "go-ipfs": "npm:mocked-go-ipfs@0.17.0", - "http-server": "^0.12.3", - "https-proxy-agent": "^5.0.0", - "image-size": "^1.0.1", - "ipfs": "0.66.0", - "ipfs-log": "^5.4.2", - "it-ws": "5.0.6", - "joi": "^17.8.1", - "level": "8.0.0", - "libp2p": "0.42.2", - "luxon": "^1.11.4", - "multiaddr": "^10.0.1", - "orbit-db": "0.29.0", - "orbit-db-access-controllers": "^0.4.0", - "orbit-db-identity-provider": "0.5.0", - "orbit-db-io": "1.0.2", - "orbit-db-pubsub": "0.6.0", - "orbit-db-store": "4.3.4", - "p-queue": "7.3.4", - "peer-id": "^0.16.0", - "pkijs": "3.0.8", - "reflect-metadata": "^0.1.13", - "rimraf": "^3.0.2", - "rxjs": "^7.2.0", - "secp256k1": "4.0.3", - "socket.io": "4.6.0", - "socks-proxy-agent": "^5.0.0", - "string-replace-loader": "3.1.0", - "ts-jest-resolver": "^2.0.0", - "validator": "^13.11.0" - }, - "overrides": { - "level": "$level", - "leveldown": "^6", - "go-ipfs": "npm:mocked-go-ipfs@0.17.0", - "orbit-db": { - "ipfs-pubsub-peer-monitor": "vinkabuki/ipfs-pubsub-peer-monitor#038af76f22e6c902dab4a855b24273707ce17d94" - } - } + "name": "@quiet/backend", + "version": "2.0.3-alpha.5", + "description": "tlg-manager", + "types": "lib/index.d.ts", + "type": "module", + "exports": "lib/index.js", + "author": "", + "license": "MIT", + "private": true, + "scripts": { + "build": "tsc -p tsconfig.build.json", + "webpack": "webpack --env mode=development && cp ./lib/bundle.cjs ../backend-bundle/bundle.cjs", + "webpack:prod": "webpack --env mode=production && cp ./lib/bundle.cjs ../backend-bundle/bundle.cjs", + "applyPatches": "patch -f -p0 < ./electron-fetch.patch || true && patch -f -p0 --forward --binary < ./parse-duration.patch || true && patch -f -p0 --forward --binary < ./parse-duration-esm.patch || true", + "prepare": "npm run applyPatches && npm run webpack", + "version": "git add -A src", + "lint": "eslint --ext .jsx,.js,.ts,.tsx ./src/ --fix", + "lint-ci": "eslint --ext .jsx,.js,.ts,.tsx ./src/", + "test-nest": "cross-env NODE_OPTIONS=--experimental-vm-modules DEBUG=ipfs:*,backend:* node_modules/jest/bin/jest.js --detectOpenHandles --forceExit ./src/nest/**/*.spec.ts", + "test": "cross-env NODE_OPTIONS=--experimental-vm-modules DEBUG=ipfs:*,backend:* node_modules/jest/bin/jest.js ./src/**/* --runInBand --verbose --testPathIgnorePatterns=\".src/(!?nodeTest*)|(.node_modules*)\"", + "test-ci": "cross-env NODE_OPTIONS=--experimental-vm-modules jest ./src/**/* --runInBand --colors --ci --silent --verbose --testPathIgnorePatterns=\".src/nest/(!?nodeTest*)|(.node_modules*)|src/nest/.*\\.tor.spec\\.(t|j)s|src/nest/ipfs-file-manager/big-files.long.spec.ts$\"", + "test-it": "cross-env NODE_OPTIONS=--experimental-vm-modules DEBUG=ipfs:*,backend:* node_modules/jest/bin/jest.js --runInBand --verbose --testPathIgnorePatterns=\".src/(!?nodeTest*)|(.node_modules*)\" --", + "test-ci-tor": "cross-env NODE_OPTIONS=--experimental-vm-modules jest --runInBand --colors --ci --silent --verbose --detectOpenHandles --forceExit ./src/nest/**/*.tor.spec.ts", + "test-ci-long-running": "cross-env DEBUG=backend:* NODE_OPTIONS=--experimental-vm-modules jest --colors --ci --verbose ./src/nest/**/*.long.spec.ts", + "test-connect": "cross-env NODE_OPTIONS=--experimental-vm-modules DEBUG='libp2p:websockets*' jest ./src/nodeTest/* --verbose", + "test-connect-ci": "cross-env NODE_OPTIONS=--experimental-vm-modules jest ./src/nodeTest/* --colors --ci --silent --verbose", + "test-replication-no-tor": "cross-env NODE_OPTIONS=--experimental-vm-modules ts-node -v && cross-env DEBUG='backend:dbSnap*,backend:localTest*' ts-node src/nodeTest/testReplicate.ts --nodesCount 1 --timeThreshold 200 --entriesCount 1000 --no-useTor", + "test-replication-tor": "cross-env NODE_OPTIONS=--experimental-vm-modules cross-env DEBUG='backend:dbSnap*,backend:localTest*' ts-node src/nodeTest/testReplicate.ts --nodesCount 1 --timeThreshold 500 --entriesCount 1000 --useTor", + "rmDist": "rimraf lib/" + }, + "repository": { + "type": "git", + "url": "git+ssh://git@github.com:TryQuiet/backend.git" + }, + "files": [ + "lib/**/*", + "package-lock.json" + ], + "jest": { + "preset": "ts-jest/presets/default-esm", + "clearMocks": true, + "coverageProvider": "v8", + "transformIgnorePatterns": [ + "node_modules/(?!p-defer|peer-id)" + ], + "testTimeout": 40000, + "setupFiles": [ + "./jestSetup.js" + ], + "testEnvironment": "jest-environment-node" + }, + "devDependencies": { + "@nestjs/cli": "^10.2.1", + "@nestjs/schematics": "^10.0.3", + "@nestjs/testing": "^10.2.10", + "@quiet/eslint-config": "^2.0.2-alpha.0", + "@quiet/state-manager": "^2.0.2-alpha.3", + "@types/crypto-js": "^4.0.2", + "@types/express": "^4.17.9", + "@types/jest": "28.1.8", + "@types/luxon": "^3.3.0", + "@types/mock-fs": "^4.13.1", + "@types/node": "18.11.9", + "@types/node-fetch": "^2.5.11", + "@types/orbit-db": "git+https://github.com/orbitdb/orbit-db-types.git", + "@types/supertest": "^2.0.11", + "@types/tmp": "^0.2.3", + "@types/validator": "^13.11.5", + "@types/ws": "8.5.3", + "babel-jest": "^29.3.1", + "cross-env": "^5.2.0", + "fetch-mock-jest": "^1.5.1", + "jest": "^29.4.2", + "mock-fs": "^5.1.2", + "tmp": "^0.2.1", + "ts-jest": "^29.0.3", + "ts-loader": "9.4.2", + "ts-node": "10.9.1", + "typescript": "^4.9.3", + "wait-for-expect": "^3.0.2", + "webpack": "5.75.0", + "webpack-cli": "5.0.1", + "yargs": "^17.1.0" + }, + "dependencies": { + "@chainsafe/libp2p-gossipsub": "6.1.0", + "@chainsafe/libp2p-noise": "11.0.0", + "@nestjs/common": "^10.2.10", + "@nestjs/core": "^10.2.10", + "@nestjs/platform-express": "^10.2.10", + "@peculiar/webcrypto": "1.4.3", + "@quiet/common": "^2.0.2-alpha.1", + "@quiet/identity": "^2.0.2-alpha.2", + "@quiet/logger": "^2.0.2-alpha.0", + "@quiet/types": "^2.0.2-alpha.1", + "abortable-iterator": "^3.0.0", + "class-transformer": "^0.5.1", + "class-validator": "^0.13.1", + "cli-table": "^0.3.6", + "commander": "^7.2.0", + "cors": "^2.8.5", + "crypto-js": "^4.1.1", + "debug": "^4.3.1", + "dotenv": "8.2.0", + "events": "^3.2.0", + "express": "^4.17.1", + "get-port": "^5.1.1", + "go-ipfs": "npm:mocked-go-ipfs@0.17.0", + "http-server": "^0.12.3", + "https-proxy-agent": "^5.0.0", + "image-size": "^1.0.1", + "ipfs": "0.66.0", + "ipfs-log": "^5.4.2", + "it-ws": "5.0.6", + "joi": "^17.8.1", + "level": "8.0.0", + "libp2p": "0.42.2", + "luxon": "^1.11.4", + "multiaddr": "^10.0.1", + "orbit-db": "0.29.0", + "orbit-db-access-controllers": "^0.4.0", + "orbit-db-identity-provider": "0.5.0", + "orbit-db-io": "1.0.2", + "orbit-db-pubsub": "0.6.0", + "orbit-db-store": "4.3.4", + "p-queue": "7.3.4", + "peer-id": "^0.16.0", + "pkijs": "3.0.8", + "reflect-metadata": "^0.1.13", + "rimraf": "^3.0.2", + "rxjs": "^7.2.0", + "secp256k1": "4.0.3", + "socket.io": "4.6.0", + "socks-proxy-agent": "^5.0.0", + "string-replace-loader": "3.1.0", + "ts-jest-resolver": "^2.0.0", + "validator": "^13.11.0" + }, + "overrides": { + "level": "$level", + "leveldown": "^6", + "go-ipfs": "npm:mocked-go-ipfs@0.17.0", + "orbit-db": { + "ipfs-pubsub-peer-monitor": "vinkabuki/ipfs-pubsub-peer-monitor#038af76f22e6c902dab4a855b24273707ce17d94" + } + } } diff --git a/packages/backend/src/backendManager.ts b/packages/backend/src/backendManager.ts index b0abe6066e..abe94f7647 100644 --- a/packages/backend/src/backendManager.ts +++ b/packages/backend/src/backendManager.ts @@ -58,8 +58,7 @@ export const runBackendDesktop = async () => { appDataPath: path.join(options.appDataPath.trim(), 'Quiet'), }, }, - }), - { logger: false } + }) ) const connectionsManager = app.get(ConnectionsManagerService) diff --git a/packages/backend/src/nest/connections-manager/connections-manager.service.ts b/packages/backend/src/nest/connections-manager/connections-manager.service.ts index 5784f38fc3..f1993d44c2 100644 --- a/packages/backend/src/nest/connections-manager/connections-manager.service.ts +++ b/packages/backend/src/nest/connections-manager/connections-manager.service.ts @@ -42,7 +42,6 @@ import { PeerId as PeerIdType, SaveCSRPayload, CommunityMetadata, - CommunityMetadataPayload, } from '@quiet/types' import { CONFIG_OPTIONS, QUIET_DIR, SERVER_IO_PROVIDER, SOCKS_PROXY_AGENT } from '../const' import { ConfigOptions, GetPorts, ServerIoProviderTypes } from '../types' @@ -181,9 +180,6 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI this.logger('reset CsrReplicated map and id') this.storageService.resetCsrReplicatedMapAndId() } - // if (this.storageService.ipfs) { - // this.storageService.ipfs = null - // } if (this.serverIoProvider?.io) { this.logger('Closing socket server') this.serverIoProvider.io.close() @@ -271,14 +267,9 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI this.logger(`Sending network data for ${community.id}`) - const payload: ResponseCreateNetworkPayload = { - community: { - ...community, - privateKey: network2.hiddenService.privateKey, - registrarUrl: community.registrarUrl || network2.hiddenService.onionAddress.split('.')[0], // TODO: remove - }, - network, - } + // It might be nice to save the entire Community in LevelDB rather + // than specific pieces of information. + const psk = community.psk if (psk) { this.logger('Creating network: received Libp2p PSK') @@ -294,6 +285,21 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI await this.localDbService.put(LocalDBKeys.PSK, psk) } + const ownerOrbitDbIdentity = community.ownerOrbitDbIdentity + if (ownerOrbitDbIdentity) { + this.logger("Creating network: received owner's OrbitDB identity") + await this.localDbService.putOwnerOrbitDbIdentity(ownerOrbitDbIdentity) + } + + const payload: ResponseCreateNetworkPayload = { + community: { + ...community, + privateKey: network2.hiddenService.privateKey, + registrarUrl: community.registrarUrl || network2.hiddenService.onionAddress.split('.')[0], // TODO: remove + }, + network, + } + this.serverIoProvider.io.emit(SocketActionTypes.NETWORK, payload) } @@ -317,6 +323,8 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI public async launchCommunity(payload: InitCommunityPayload) { this.logger('Launching community: peers:', payload.peers) this.communityState = ServiceState.LAUNCHING + // Perhaps we should call this data something else, since we already have a Community type. + // It seems like InitCommunityPayload is a mix of various connection metadata. const communityData: InitCommunityPayload = await this.localDbService.get(LocalDBKeys.COMMUNITY) if (!communityData) { await this.localDbService.put(LocalDBKeys.COMMUNITY, payload) @@ -330,6 +338,7 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI type: SocketActionTypes.COMMUNITY, message: ErrorMessages.COMMUNITY_LAUNCH_FAILED, community: payload.id, + trace: e.stack, }) return } @@ -348,6 +357,7 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI this.serverIoProvider.io.emit(SocketActionTypes.COMMUNITY, { id: payload.id }) } + public async launch(payload: InitCommunityPayload) { // Start existing community (community that user is already a part of) this.logger(`Spawning hidden service for community ${payload.id}, peer: ${payload.peerId.id}`) @@ -416,6 +426,7 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI await this.storageService.init(_peerId) this.logger('storage initialized') } + private attachTorEventsListeners() { this.logger('attachTorEventsListeners') @@ -482,7 +493,7 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI } }) this.socketService.on(SocketActionTypes.SEND_COMMUNITY_METADATA, async (payload: CommunityMetadata) => { - await this.storageService?.updateCommunityMetadata(payload) + const meta = await this.storageService?.communityMetadataStore?.updateCommunityMetadata(payload) }) this.socketService.on(SocketActionTypes.SAVE_USER_CSR, async (payload: SaveCSRPayload) => { this.logger(`socketService - ${SocketActionTypes.SAVE_USER_CSR}`) @@ -610,13 +621,9 @@ export class ConnectionsManagerService extends EventEmitter implements OnModuleI this.registrationService.emit(RegistrationEvents.REGISTER_USER_CERTIFICATE, payload) } ) - this.storageService.on(StorageEvents.REPLICATED_COMMUNITY_METADATA, (payload: CommunityMetadata) => { - this.logger(`Storage - ${StorageEvents.REPLICATED_COMMUNITY_METADATA}: ${payload}`) - const communityMetadataPayload: CommunityMetadataPayload = { - rootCa: payload.rootCa, - ownerCertificate: payload.ownerCertificate, - } - this.serverIoProvider.io.emit(SocketActionTypes.SAVE_COMMUNITY_METADATA, communityMetadataPayload) + this.storageService.on(StorageEvents.COMMUNITY_METADATA_SAVED, (meta: CommunityMetadata) => { + this.logger(`Storage - ${StorageEvents.COMMUNITY_METADATA_SAVED}: ${meta}`) + this.serverIoProvider.io.emit(SocketActionTypes.COMMUNITY_METADATA_SAVED, meta) }) } } diff --git a/packages/backend/src/nest/local-db/local-db.service.ts b/packages/backend/src/nest/local-db/local-db.service.ts index f5275ff77f..e537224e06 100644 --- a/packages/backend/src/nest/local-db/local-db.service.ts +++ b/packages/backend/src/nest/local-db/local-db.service.ts @@ -76,4 +76,12 @@ export class LocalDbService { const stats: NetworkStats[] = Object.values(peersStats) return filterAndSortPeers(peers, stats) } + + public async putOwnerOrbitDbIdentity(id: string): Promise { + this.put(LocalDBKeys.OWNER_ORBIT_DB_IDENTITY, id) + } + + public async getOwnerOrbitDbIdentity(): Promise { + return this.get(LocalDBKeys.OWNER_ORBIT_DB_IDENTITY) + } } diff --git a/packages/backend/src/nest/local-db/local-db.types.ts b/packages/backend/src/nest/local-db/local-db.types.ts index 1834f0a062..aded572cec 100644 --- a/packages/backend/src/nest/local-db/local-db.types.ts +++ b/packages/backend/src/nest/local-db/local-db.types.ts @@ -3,5 +3,6 @@ export enum LocalDBKeys { REGISTRAR = 'registrar', PEERS = 'peers', PSK = 'psk', + OWNER_ORBIT_DB_IDENTITY = 'ownerOrbitDbIdentity', } export type LocalDbStatus = 'opening' | 'open' | 'closing' | 'closed' diff --git a/packages/backend/src/nest/registration/registration.service.ts b/packages/backend/src/nest/registration/registration.service.ts index 2f6e0d90d9..d245239755 100644 --- a/packages/backend/src/nest/registration/registration.service.ts +++ b/packages/backend/src/nest/registration/registration.service.ts @@ -19,13 +19,18 @@ export class RegistrationService extends EventEmitter implements OnModuleInit { this.on( RegistrationEvents.REGISTER_USER_CERTIFICATE, async (payload: { csrs: string[]; certificates: string[]; id: string }) => { - // Lack of permsData means that we are not the owner of the community in the official model of the app, however anyone can modify the source code, put malicious permsData here, issue false certificates and try to trick other users. await this.issueCertificates(payload) } ) } private async issueCertificates(payload: { csrs: string[]; certificates: string[]; id?: string }) { + // Lack of permsData means that we are not the owner of the + // community in the official model of the app, however anyone can + // modify the source code, put malicious permsData here, issue + // false certificates and try to trick other users. To prevent + // that, peers verify that anything that is written to the + // certificate store is signed by the owner. if (!this._permsData) { if (payload.id) this.emit(RegistrationEvents.FINISHED_ISSUING_CERTIFICATES_FOR_ID, { id: payload.id }) return diff --git a/packages/backend/src/nest/socket/socket.service.ts b/packages/backend/src/nest/socket/socket.service.ts index b1218cb7ec..2e02ec86d7 100644 --- a/packages/backend/src/nest/socket/socket.service.ts +++ b/packages/backend/src/nest/socket/socket.service.ts @@ -171,8 +171,8 @@ export class SocketService extends EventEmitter implements OnModuleInit { const communityMetadataPayload: CommunityMetadata = { id: payload.id, - ownerCertificate: payload.certificate, rootCa: payload.permsData.certificate, + ownerCertificate: payload.certificate, } this.emit(SocketActionTypes.SEND_COMMUNITY_METADATA, communityMetadataPayload) }) diff --git a/packages/backend/src/nest/storage/communityMetadata/communityMetadata.store.spec.ts b/packages/backend/src/nest/storage/communityMetadata/communityMetadata.store.spec.ts new file mode 100644 index 0000000000..c7832205e0 --- /dev/null +++ b/packages/backend/src/nest/storage/communityMetadata/communityMetadata.store.spec.ts @@ -0,0 +1,151 @@ +import { jest, beforeEach, describe, it, expect, afterEach, beforeAll, test } from '@jest/globals' +import OrbitDB from 'orbit-db' +import { EventEmitter } from 'events' +import { IdentityProvider } from 'orbit-db-identity-provider' + +import { CommunityMetadataStore } from './communityMetadata.store' +import { LocalDbService } from '../../local-db/local-db.service' + +const mockOrbitDbStore = { + load: jest.fn(), + get: jest.fn(), + put: jest.fn(), + events: { on: jest.fn() }, + all: {}, +} +const mockOrbitDb = { + identity: { id: 'theOwnerId', provider: jest.fn() }, + keyvalue: jest.fn( + (): { + load: jest.Mock + get: jest.Mock + put: jest.Mock + events: { on: jest.Mock } + all: object + } => { + return mockOrbitDbStore + } + ), +} +const mockLocalDbService = { putOwnerOrbitDbIdentity: jest.fn(), getOwnerOrbitDbIdentity: jest.fn(() => 'theOwnerId') } +const mockEmitter = { emit: jest.fn() } + +const metaValid = { + id: 'anId', + rootCa: + 'MIIBRTCB7KADAgECAgEBMAoGCCqGSM49BAMCMAwxCjAIBgNVBAMTAWEwHhcNMTAxMjI4MTAxMDEwWhcNMzAxMjI4MTAxMDEwWjAMMQowCAYDVQQDEwFhMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbifF9IqU0464LTet/71bqXFrIZN6mjQ/eXYEcVJU4nenXx1Br7ZavvtzS7q/wCdy0y4C4thy+5IfrJzxvSxqPqM/MD0wDwYDVR0TBAgwBgEB/wIBAzALBgNVHQ8EBAMCAIYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMAoGCCqGSM49BAMCA0gAMEUCIQDADbVTK4Tn4pqEffh3zMXgAgrw4lpndAvoa/VmJBeWcgIgVWoI6JC9xT3SKX2oaUoWrv5/hbi5s9+FOCHnAYrK+uo=', + ownerCertificate: + 'MIIBRTCB7KADAgECAgEBMAoGCCqGSM49BAMCMAwxCjAIBgNVBAMTAWEwHhcNMTAxMjI4MTAxMDEwWhcNMzAxMjI4MTAxMDEwWjAMMQowCAYDVQQDEwFhMFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEbifF9IqU0464LTet/71bqXFrIZN6mjQ/eXYEcVJU4nenXx1Br7ZavvtzS7q/wCdy0y4C4thy+5IfrJzxvSxqPqM/MD0wDwYDVR0TBAgwBgEB/wIBAzALBgNVHQ8EBAMCAIYwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMBMAoGCCqGSM49BAMCA0gAMEUCIQDADbVTK4Tn4pqEffh3zMXgAgrw4lpndAvoa/VmJBeWcgIgVWoI6JC9xT3SKX2oaUoWrv5/hbi5s9+FOCHnAYrK+uo=', +} + +const metaValidWithOwnerId = { + ...metaValid, + ownerOrbitDbIdentity: 'theOwnerId', +} + +const entryValid = { + payload: { op: 'PUT', key: metaValidWithOwnerId.id, value: metaValidWithOwnerId }, + // These fields are not checked currently + hash: '', + id: '', + next: [''], + v: 1, + clock: { + // Not sure why this type is defined like this: + // https://github.com/orbitdb/orbit-db-types/blob/ed41369e64c054952c1e47505d598342a4967d4c/LogEntry.d.ts#L8C9-L8C17 + id: '' as 'string', + time: 1, + }, + key: '', + identity: { + // NOTE: This is where the entry identity is defined! + id: 'theOwnerId', + publicKey: '', + signatures: { id: '', publicKey: '' }, + type: '', + }, + sig: '', +} + +describe('CommmunityMetadataStore/updateCommunityMetadata', () => { + test('updates community metadata if the metadata is valid', async () => { + const store = new CommunityMetadataStore() + await store.init( + mockOrbitDb as unknown as OrbitDB, + mockLocalDbService as unknown as LocalDbService, + mockEmitter as unknown as EventEmitter + ) + const ret = await store.updateCommunityMetadata(metaValid) + + expect(ret).toStrictEqual(metaValidWithOwnerId) + expect(mockOrbitDb.keyvalue().put.mock.calls).toEqual([[metaValidWithOwnerId.id, metaValidWithOwnerId]]) + }) + + test('does not update community metadata if the metadata is invalid', async () => { + const metaInvalid = { + ...metaValid, + rootCa: 'Something invalid!', + } + const store = new CommunityMetadataStore() + await store.init( + mockOrbitDb as unknown as OrbitDB, + mockLocalDbService as unknown as LocalDbService, + mockEmitter as unknown as EventEmitter + ) + const ret = await store.updateCommunityMetadata(metaInvalid) + + expect(ret).toStrictEqual(undefined) + expect(mockOrbitDb.keyvalue().put.mock.calls).toEqual([]) + }) +}) + +describe('CommmunityMetadataStore/validateCommunityMetadataEntry', () => { + test('returns true if the owner ID is expected and entry is otherwise valid', async () => { + const ret = await CommunityMetadataStore.validateCommunityMetadataEntry( + mockLocalDbService as unknown as LocalDbService, + { verifyIdentity: jest.fn(() => true) } as unknown as typeof IdentityProvider, + entryValid + ) + + expect(ret).toEqual(true) + }) + + test('returns false if the owner ID is unexpected and entry is otherwise valid', async () => { + const entryInvalid = { + ...entryValid, + identity: { + // NOTE: This is where the entry identity is defined! + id: 'Not the owner!', + publicKey: '', + signatures: { id: '', publicKey: '' }, + type: '', + }, + } + const ret = await CommunityMetadataStore.validateCommunityMetadataEntry( + mockLocalDbService as unknown as LocalDbService, + { verifyIdentity: jest.fn(() => true) } as unknown as typeof IdentityProvider, + entryInvalid + ) + expect(ret).toEqual(false) + }) + + test('returns false if the owner cert is unexpected and entry is otherwise valid', async () => { + const entryInvalid = { + ...entryValid, + payload: { + op: 'PUT', + key: metaValidWithOwnerId.id, + value: { + ...metaValidWithOwnerId, + rootCa: 'Something invalid!', + }, + }, + } + const ret = await CommunityMetadataStore.validateCommunityMetadataEntry( + mockLocalDbService as unknown as LocalDbService, + { verifyIdentity: jest.fn(() => true) } as unknown as typeof IdentityProvider, + entryInvalid + ) + expect(ret).toEqual(false) + }) +}) diff --git a/packages/backend/src/nest/storage/communityMetadata/communityMetadata.store.ts b/packages/backend/src/nest/storage/communityMetadata/communityMetadata.store.ts new file mode 100644 index 0000000000..9d5c7f5785 --- /dev/null +++ b/packages/backend/src/nest/storage/communityMetadata/communityMetadata.store.ts @@ -0,0 +1,222 @@ +import { Injectable } from '@nestjs/common' +import { EventEmitter } from 'events' +import KeyValueStore from 'orbit-db-kvstore' +import OrbitDB from 'orbit-db' +import { getCrypto, ICryptoEngine } from 'pkijs' +import { sha256 } from 'multiformats/hashes/sha2' +import { stringToArrayBuffer } from 'pvutils' +import * as Block from 'multiformats/block' +import * as dagCbor from '@ipld/dag-cbor' +import { IdentityProvider } from 'orbit-db-identity-provider' + +import { CommunityMetadata, NoCryptoEngineError } from '@quiet/types' +import { keyFromCertificate, keyObjectFromString, loadCertificate } from '@quiet/identity' + +import { StorageEvents } from '../storage.types' +import createLogger from '../../common/logger' +import { KeyValueIndex } from '../orbitDb/keyValueIndex' +import { LocalDbService } from '../../local-db/local-db.service' + +const logger = createLogger('CommunityMetadataStore') + +/** + * Helper function that allows one to use partial-application with a + * constructor. Given a classname and constructor params, returns a + * new constructor which can be called like normal (`new x()`). + * + * This is useful because in OrbitDB they expect the store index to be + * constructable with zero arguments, so they call it with the `new` + * keyword. + */ +function constructPartial(constructor: (...args: any[]) => any, args: any[]) { + return constructor.bind.apply(constructor, [null, ...args]) +} + +export class CommunityMetadataStore { + public orbitDb: OrbitDB + public store: KeyValueStore + private localDbService: LocalDbService + + // Copying OrbitDB by using dag-cbor/sha256 for converting the + // profile to a byte array for signing: + // https://github.com/orbitdb/orbitdb/blob/3eee148510110a7b698036488c70c5c78f868cd9/src/oplog/entry.js#L75-L76 + // I think any encoding would work here. + public static readonly codec = dagCbor + public static readonly hasher = sha256 + + constructor() {} + + public async init(orbitDb: OrbitDB, localDbService: LocalDbService, emitter: EventEmitter) { + logger('Initializing community metadata key/value store') + + this.orbitDb = orbitDb + this.localDbService = localDbService + + // If the owner initializes the CommunityMetadataStore, then the + // ID would be undefined at this point when they first create the + // community. This would mean that they wouldn't be able to to + // validate an entry's ownership when writing or replicating. + // + // As a quick solution, we dynamically retrieve the owner's + // identity in the validation function. So after the owner sets it + // when calling updateCommunityMetadata, the validation function + // could then retrieve it. In our case, this is probably fine, + // because only the owner would be in the network by the time they + // first call updateCommunityMetadata. + // + // However, I think it might be simpler to pass the owner's + // OrbitDB identity when creating the store. For this we need to + // know at the time of initialization whether or not someone is + // the owner. + this.store = await this.orbitDb.keyvalue('community-metadata', { + replicate: false, + // Partially construct index so that we can include an + // IdentityProvider in the index validation logic. + // @ts-expect-error - OrbitDB's type declaration of OrbitDB lacks identity + Index: constructPartial(CommunityMetadataKeyValueIndex, [orbitDb.identity.provider, this.localDbService]), + accessController: { + write: ['*'], + }, + }) + + this.store.events.on('write', (_address, entry) => { + logger('Saved community metadata locally') + emitter.emit(StorageEvents.COMMUNITY_METADATA_SAVED, entry.payload.value) + }) + + this.store.events.on('replicated', async () => { + logger('Replicated community metadata') + // @ts-expect-error - OrbitDB's type declaration of `load` lacks 'options' + // TODO: Is this necessary here? + await this.store.load({ fetchEntryTimeout: 15000 }) + const meta = await this.getCommunityMetadata() + if (meta) { + emitter.emit(StorageEvents.COMMUNITY_METADATA_SAVED, meta) + } + }) + + // @ts-expect-error - OrbitDB's type declaration of `load` lacks 'options' + await this.store.load({ fetchEntryTimeout: 15000 }) + logger('Loaded community metadata to memory') + const meta = await this.getCommunityMetadata() + if (meta) { + emitter.emit(StorageEvents.COMMUNITY_METADATA_SAVED, meta) + } + } + + public getAddress() { + return this.store?.address + } + + public async close() { + await this.store?.close() + } + + public async updateCommunityMetadata(newMeta: CommunityMetadata): Promise { + try { + // TODO: Also check OrbitDB identity when updating community metadata + const valid = await CommunityMetadataStore.validateCommunityMetadata(newMeta) + if (!valid) { + // TODO: Send validation errors to frontend or replicate + // validation on frontend? + logger.error('Failed to update community metadata') + return + } + + logger(`About to update community metadata`) + if (!newMeta.id) return + + // FIXME: update community metadata if it has changed (so that + // we can migrate community metadata easily) + const oldMeta = this.store.get(newMeta.id) + if (oldMeta?.ownerCertificate && oldMeta?.rootCa) { + return oldMeta + } + + logger(`Updating community metadata`) + // @ts-expect-error - OrbitDB's type declaration of OrbitDB lacks identity + const ownerOrbitDbIdentity = this.orbitDb.identity.id + const meta = { + ...oldMeta, + ...newMeta, + ownerOrbitDbIdentity, + } + await this.store.put(meta.id, meta) + + this.localDbService.putOwnerOrbitDbIdentity(ownerOrbitDbIdentity) + + return meta + } catch (err) { + logger.error('Failed to add community metadata', err) + } + } + + public static async validateCommunityMetadata(communityMetadata: CommunityMetadata): Promise { + // FIXME: Add additional validation to verify communityMetadata + // contains required fields. + + try { + const crypto = getCrypto() + if (!crypto) { + throw new NoCryptoEngineError() + } + + // TODO: Should we sign community metadata with root private key + // and verify? I'm not sure it matters that much. + + const rootCert = loadCertificate(communityMetadata.rootCa) + const ownerCert = loadCertificate(communityMetadata.ownerCertificate) + + // Verify that owner certificate is signed by root certificate + return await ownerCert.verify(rootCert) + } catch (err) { + logger.error('Failed to validate community metadata:', communityMetadata.id, err?.message) + return false + } + } + + public static async validateCommunityMetadataEntry( + localDbService: LocalDbService, + identityProvider: typeof IdentityProvider, + entry: LogEntry + ): Promise { + try { + if (entry.payload.key !== entry.payload.value.id) { + logger.error('Failed to verify community metadata entry:', entry.hash, 'entry key != payload id') + return false + } + + const ownerOrbitDbIdentity = await localDbService.getOwnerOrbitDbIdentity() + if (entry.identity.id !== ownerOrbitDbIdentity) { + logger.error('Failed to verify community metadata entry:', entry.hash, 'entry identity != owner identity') + return false + } + + const identityVerified = await identityProvider.verifyIdentity(entry.identity) + if (!identityVerified) { + logger.error('Failed to verify community metadata entry:', entry.hash, 'entry verification failed') + return false + } + + const valid = await CommunityMetadataStore.validateCommunityMetadata(entry.payload.value) + return valid + } catch (err) { + logger.error('Failed to verify community metadata entry:', entry.hash, err?.message) + return false + } + } + + public async getCommunityMetadata(): Promise { + const metadata = Object.values(this.store.all) + + if (metadata.length > 0) { + return metadata[0] + } + } +} + +export class CommunityMetadataKeyValueIndex extends KeyValueIndex { + constructor(identityProvider: typeof IdentityProvider, localDbService: LocalDbService) { + super(identityProvider, CommunityMetadataStore.validateCommunityMetadataEntry.bind(null, localDbService)) + } +} diff --git a/packages/backend/src/nest/storage/orbitDb/keyValueIndex.spec.ts b/packages/backend/src/nest/storage/orbitDb/keyValueIndex.spec.ts new file mode 100644 index 0000000000..1a8b8170eb --- /dev/null +++ b/packages/backend/src/nest/storage/orbitDb/keyValueIndex.spec.ts @@ -0,0 +1,44 @@ +import { jest, beforeEach, describe, it, expect, afterEach, beforeAll, test } from '@jest/globals' +import { IdentityProvider } from 'orbit-db-identity-provider' + +import { KeyValueIndex } from './keyValueIndex' + +const key = 'theKey' +const entry = { + payload: { op: 'PUT', key: key, value: 'isWithin' }, + // These fields are not checked currently + hash: '', + id: '', + next: [''], + v: 1, + clock: { + // Not sure why this type is defined like this: + // https://github.com/orbitdb/orbit-db-types/blob/ed41369e64c054952c1e47505d598342a4967d4c/LogEntry.d.ts#L8C9-L8C17 + id: '' as 'string', + time: 1, + }, + key: '', + identity: { + id: '', + publicKey: '', + signatures: { id: '', publicKey: '' }, + type: '', + }, + sig: '', +} + +describe('KeyValueIndex', () => { + test('updateIndex adds entry if it is valid', async () => { + const validateFn = async (idProvider: typeof IdentityProvider, entry: LogEntry): Promise => true + const index = new KeyValueIndex(jest.fn() as unknown as typeof IdentityProvider, validateFn) + await index.updateIndex({ values: [entry] }) + expect(index.get(key)).toEqual('isWithin') + }) + + test('updateIndex skips entry if it is invalid', async () => { + const validateFn = async (idProvider: typeof IdentityProvider, entry: LogEntry): Promise => false + const index = new KeyValueIndex(jest.fn() as unknown as typeof IdentityProvider, validateFn) + await index.updateIndex({ values: [entry] }) + expect(index.get(key)).toEqual(undefined) + }) +}) diff --git a/packages/backend/src/nest/storage/orbitDb/keyValueIndex.ts b/packages/backend/src/nest/storage/orbitDb/keyValueIndex.ts new file mode 100644 index 0000000000..1e40cb428f --- /dev/null +++ b/packages/backend/src/nest/storage/orbitDb/keyValueIndex.ts @@ -0,0 +1,63 @@ +import { IdentityProvider } from 'orbit-db-identity-provider' + +import createLogger from '../../common/logger' + +const logger = createLogger('KeyValueIndex') + +type ValidateFn = (identityProvider: typeof IdentityProvider, entry: LogEntry) => Promise + +/** + * Modified from: + * https://github.com/orbitdb/orbit-db-kvstore/blob/main/src/KeyValueIndex.js + * + * Adds validation function that validates each entry before adding it + * to the index. + * + * TODO: Save latest entry and only iterate over new entries in updateIndex + */ +export class KeyValueIndex { + private _index: Record + private validateFn: ValidateFn + private identityProvider: typeof IdentityProvider + + constructor(identityProvider: typeof IdentityProvider, validateFn: ValidateFn) { + this._index = {} + this.validateFn = validateFn + this.identityProvider = identityProvider + } + + get(key: string) { + return this._index[key] + } + + async updateIndex(oplog: { values: LogEntry[] }) { + const values: LogEntry[] = [] + const handled: Record = {} + + for (const v of oplog.values) { + if (await this.validateFn(this.identityProvider, v)) { + values.push(v) + } + } + + for (let i = values.length - 1; i >= 0; i--) { + const item = values[i] + if (typeof item.payload.key === 'string') { + if (handled[item.payload.key]) { + continue + } + handled[item.payload.key] = true + if (item.payload.op === 'PUT') { + this._index[item.payload.key] = item.payload.value + continue + } + if (item.payload.op === 'DEL') { + delete this._index[item.payload.key] + continue + } + } else { + logger.error(`Failed to update key/value index - key is not string: ${item.payload.key}`) + } + } + } +} diff --git a/packages/backend/src/nest/storage/storage.service.spec.ts b/packages/backend/src/nest/storage/storage.service.spec.ts index bece857661..3f28910ab1 100644 --- a/packages/backend/src/nest/storage/storage.service.spec.ts +++ b/packages/backend/src/nest/storage/storage.service.spec.ts @@ -259,8 +259,7 @@ describe('StorageService', () => { const channelsDbAddress = storageService.channels?.address const certificatesDbAddress = storageService.certificatesStore.getAddress() const certificatesRequestsDbAddress = storageService.certificatesRequestsStore.getAddress() - // @ts-expect-error 'communityMetadata' is private - const communityMetadataDbAddress = storageService.communityMetadata.address + const communityMetadataDbAddress = storageService.communityMetadataStore.getAddress() expect(channelsDbAddress).not.toBeFalsy() expect(certificatesDbAddress).not.toBeFalsy() expect(subscribeToPubSubSpy).toBeCalledTimes(2) diff --git a/packages/backend/src/nest/storage/storage.service.ts b/packages/backend/src/nest/storage/storage.service.ts index 8310c29751..05a3d81fcd 100644 --- a/packages/backend/src/nest/storage/storage.service.ts +++ b/packages/backend/src/nest/storage/storage.service.ts @@ -51,6 +51,7 @@ import { removeFiles, removeDirs, createPaths } from '../common/utils' import { StorageEvents } from './storage.types' import { CertificatesStore } from './certificates/certificates.store' import { CertificatesRequestsStore } from './certificatesRequestsStore' +import { CommunityMetadataStore } from './communityMetadata/communityMetadata.store' interface DBOptions { replicate: boolean @@ -58,13 +59,17 @@ interface DBOptions { @Injectable() export class StorageService extends EventEmitter { - public channels: KeyValueStore public publicChannelsRepos: Map = new Map() public directMessagesRepos: Map = new Map() private publicKeysMap: Map = new Map() - private communityMetadata: KeyValueStore - public certificatesStore: CertificatesStore + private userNamesMap: Map = new Map() + + public communityMetadataStore: CommunityMetadataStore public certificatesRequestsStore: CertificatesRequestsStore + public certificatesStore: CertificatesStore + public certificates: EventStore + public channels: KeyValueStore + private ipfs: IPFS private orbitDb: OrbitDB private filesManager: IpfsFileManagerService @@ -72,6 +77,7 @@ export class StorageService extends EventEmitter { private ipfsStarted: boolean private readonly logger = Logger(StorageService.name) + constructor( private readonly localDbService: LocalDbService, @Inject(QUIET_DIR) public readonly quietDir: string, @@ -159,8 +165,8 @@ export class StorageService extends EventEmitter { if (this.certificatesRequestsStore.getAddress()) { dbs.push(this.certificatesRequestsStore.getAddress()) } - if (this.communityMetadata?.address) { - dbs.push(this.communityMetadata.address) + if (this.communityMetadataStore?.getAddress()) { + dbs.push(this.communityMetadataStore.getAddress()) } const channels = this.publicChannelsRepos.values() @@ -215,73 +221,34 @@ export class StorageService extends EventEmitter { } public async initDatabases() { + // FIXME: I think we depend on the owner's public key from community + // metadata to validate certificates and so we can setup the + // community metadata first and if we depend on any piece of + // community metadata to validate any other stores, we can wait + // until community metadata has been replicated before + // initializing those other stores. + this.logger('1/3') + this.communityMetadataStore = new CommunityMetadataStore() + await this.communityMetadataStore.init(this.orbitDb, this.localDbService, this) + this.certificatesStore = new CertificatesStore(this.orbitDb) await this.certificatesStore.init(this) this.certificatesRequestsStore = new CertificatesRequestsStore(this.orbitDb) await this.certificatesRequestsStore.init(this) - this.logger('1/5') - await this.createDbForChannels() - this.logger('2/5') + this.logger('2/3') await this.attachCertificatesStoreListeners() - this.logger('3/5') await this.attachCsrsStoreListeners() - this.logger('4/5') - await this.createDbForCommunityMetadata() - this.logger('5/5') + this.logger('3/3') + await this.createDbForChannels() await this.initAllChannels() this.logger('Initialized DBs') this.emit(SocketActionTypes.CONNECTION_PROCESS_INFO, ConnectionProcessInfo.INITIALIZED_DBS) } - private async createDbForCommunityMetadata() { - this.logger('createDbForCommunityMetadata init') - - this.communityMetadata = await this.orbitDb.keyvalue('community-metadata', { - replicate: false, - accessController: { - write: ['*'], - }, - }) - - this.communityMetadata.events.on('write', async (_address, _entry) => { - this.logger('WRITE: communityMetadata') - const metadata = Object.values(this.communityMetadata.all)[0] - this.certificatesStore.updateMetadata(metadata) - }) - - this.communityMetadata.events.on('replicated', async () => { - this.logger('Replicated community metadata') - - const metadata = Object.values(this.communityMetadata.all)[0] - this.certificatesStore.updateMetadata(metadata) - - // @ts-expect-error - OrbitDB's type declaration of `load` lacks 'options' - await this.communityMetadata.load({ fetchEntryTimeout: 15000 }) - this.emit(StorageEvents.REPLICATED_COMMUNITY_METADATA, metadata) - }) - - // @ts-expect-error - OrbitDB's type declaration of `load` lacks 'options' - await this.communityMetadata.load({ fetchEntryTimeout: 15000 }) - - const metadata = Object.values(this.communityMetadata.all)[0] - this.certificatesStore.updateMetadata(metadata) - } - - public async updateCommunityMetadata(communityMetadata: CommunityMetadata) { - this.logger(`About to update community metadata`) - if (!communityMetadata.id) return - const meta = this.communityMetadata.get(communityMetadata.id) - if (meta?.ownerCertificate && meta?.rootCa) return - this.logger(`Updating community metadata`) - await this.communityMetadata.put(communityMetadata.id, { - ...meta, - ...communityMetadata, - }) - } private async __stopOrbitDb() { if (this.orbitDb) { @@ -332,9 +299,9 @@ export class StorageService extends EventEmitter { } try { - await this.communityMetadata?.close() + await this.communityMetadataStore?.close() } catch (e) { - this.logger.error('Error closing community metadata db', e) + this.logger.error('Error closing community metadata store', e) } await this.__stopOrbitDb() @@ -842,7 +809,7 @@ export class StorageService extends EventEmitter { // @ts-ignore this.certificatesRequests = undefined // @ts-ignore - this.communityMetadata = undefined + this.communityMetadataStore = undefined this.publicChannelsRepos = new Map() this.directMessagesRepos = new Map() this.publicKeysMap = new Map() diff --git a/packages/backend/src/nest/storage/storage.types.ts b/packages/backend/src/nest/storage/storage.types.ts index 0963a18bbb..f80f0f3206 100644 --- a/packages/backend/src/nest/storage/storage.types.ts +++ b/packages/backend/src/nest/storage/storage.types.ts @@ -21,13 +21,13 @@ export enum StorageEvents { LOAD_ALL_DIRECT_MESSAGES = 'loadAllDirectMessages', // Misc SEND_PUSH_NOTIFICATION = 'sendPushNotification', - // Community - REPLICATED_COMMUNITY_METADATA = 'replicatedCommunityMetadata', // Users LOADED_USER_CSRS = 'loadedUserCsrs', REPLICATED_CSR = 'replicatedCsr', LOADED_CERTIFICATES = 'loadedCertificates', REPLICATED_CERTIFICATES = 'replicatedCertificates', + // Community + COMMUNITY_METADATA_SAVED = 'communityMetadataSaved', } export interface InitStorageParams { communityId: string diff --git a/packages/common/package-lock.json b/packages/common/package-lock.json index f59a8c3632..8e6302db19 100644 --- a/packages/common/package-lock.json +++ b/packages/common/package-lock.json @@ -983,88 +983,6 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, - "node_modules/@peculiar/webcrypto": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.3.tgz", - "integrity": "sha512-VtaY4spKTdN5LjJ04im/d/joXuvLbQdgy5Z4DXF4MFZhQ+MTrejbNMkfZBp1Bs3O5+bFqnJgyGdPuZQflvIa5A==", - "dependencies": { - "@peculiar/asn1-schema": "^2.3.6", - "@peculiar/json-schema": "^1.1.12", - "pvtsutils": "^1.3.2", - "tslib": "^2.5.0", - "webcrypto-core": "^1.7.7" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/@peculiar/webcrypto/node_modules/@peculiar/asn1-schema": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.8.tgz", - "integrity": "sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA==", - "dependencies": { - "asn1js": "^3.0.5", - "pvtsutils": "^1.3.5", - "tslib": "^2.6.2" - } - }, - "node_modules/@peculiar/webcrypto/node_modules/@peculiar/json-schema": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", - "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@peculiar/webcrypto/node_modules/asn1js": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz", - "integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==", - "dependencies": { - "pvtsutils": "^1.3.2", - "pvutils": "^1.1.3", - "tslib": "^2.4.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@peculiar/webcrypto/node_modules/pvtsutils": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.5.tgz", - "integrity": "sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==", - "dependencies": { - "tslib": "^2.6.1" - } - }, - "node_modules/@peculiar/webcrypto/node_modules/pvutils": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", - "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@peculiar/webcrypto/node_modules/tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "node_modules/@peculiar/webcrypto/node_modules/webcrypto-core": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.7.tgz", - "integrity": "sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g==", - "dependencies": { - "@peculiar/asn1-schema": "^2.3.6", - "@peculiar/json-schema": "^1.1.12", - "asn1js": "^3.0.1", - "pvtsutils": "^1.3.2", - "tslib": "^2.4.0" - } - }, "node_modules/@sinonjs/commons": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", @@ -7064,78 +6982,6 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, - "@peculiar/webcrypto": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/@peculiar/webcrypto/-/webcrypto-1.4.3.tgz", - "integrity": "sha512-VtaY4spKTdN5LjJ04im/d/joXuvLbQdgy5Z4DXF4MFZhQ+MTrejbNMkfZBp1Bs3O5+bFqnJgyGdPuZQflvIa5A==", - "requires": { - "@peculiar/asn1-schema": "^2.3.6", - "@peculiar/json-schema": "^1.1.12", - "pvtsutils": "^1.3.2", - "tslib": "^2.5.0", - "webcrypto-core": "^1.7.7" - }, - "dependencies": { - "@peculiar/asn1-schema": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/@peculiar/asn1-schema/-/asn1-schema-2.3.8.tgz", - "integrity": "sha512-ULB1XqHKx1WBU/tTFIA+uARuRoBVZ4pNdOA878RDrRbBfBGcSzi5HBkdScC6ZbHn8z7L8gmKCgPC1LHRrP46tA==", - "requires": { - "asn1js": "^3.0.5", - "pvtsutils": "^1.3.5", - "tslib": "^2.6.2" - } - }, - "@peculiar/json-schema": { - "version": "1.1.12", - "resolved": "https://registry.npmjs.org/@peculiar/json-schema/-/json-schema-1.1.12.tgz", - "integrity": "sha512-coUfuoMeIB7B8/NMekxaDzLhaYmp0HZNPEjYRm9goRou8UZIC3z21s0sL9AWoCw4EG876QyO3kYrc61WNF9B/w==", - "requires": { - "tslib": "^2.0.0" - } - }, - "asn1js": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/asn1js/-/asn1js-3.0.5.tgz", - "integrity": "sha512-FVnvrKJwpt9LP2lAMl8qZswRNm3T4q9CON+bxldk2iwk3FFpuwhx2FfinyitizWHsVYyaY+y5JzDR0rCMV5yTQ==", - "requires": { - "pvtsutils": "^1.3.2", - "pvutils": "^1.1.3", - "tslib": "^2.4.0" - } - }, - "pvtsutils": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/pvtsutils/-/pvtsutils-1.3.5.tgz", - "integrity": "sha512-ARvb14YB9Nm2Xi6nBq1ZX6dAM0FsJnuk+31aUp4TrcZEdKUlSqOqsxJHUPJDNE3qiIp+iUPEIeR6Je/tgV7zsA==", - "requires": { - "tslib": "^2.6.1" - } - }, - "pvutils": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/pvutils/-/pvutils-1.1.3.tgz", - "integrity": "sha512-pMpnA0qRdFp32b1sJl1wOJNxZLQ2cbQx+k6tjNtZ8CpvVhNqEPRgivZ2WOUev2YMajecdH7ctUPDvEe87nariQ==" - }, - "tslib": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", - "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==" - }, - "webcrypto-core": { - "version": "1.7.7", - "resolved": "https://registry.npmjs.org/webcrypto-core/-/webcrypto-core-1.7.7.tgz", - "integrity": "sha512-7FjigXNsBfopEj+5DV2nhNpfic2vumtjjgPmeDKk45z+MJwXKKfhPB7118Pfzrmh4jqOMST6Ch37iPAHoImg5g==", - "requires": { - "@peculiar/asn1-schema": "^2.3.6", - "@peculiar/json-schema": "^1.1.12", - "asn1js": "^3.0.1", - "pvtsutils": "^1.3.2", - "tslib": "^2.4.0" - } - } - } - }, "@sinonjs/commons": { "version": "1.8.6", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", diff --git a/packages/common/src/invitationCode.test.ts b/packages/common/src/invitationCode.test.ts index 7ef34257cb..5f18ae4378 100644 --- a/packages/common/src/invitationCode.test.ts +++ b/packages/common/src/invitationCode.test.ts @@ -16,6 +16,7 @@ describe('Invitation code helper', () => { const address2 = 'y7yczmugl2tekami7sbdz5pfaemvx7bahwthrdvcbzw5vex2crsr26qd' const psk = 'BNlxfE2WBF7LrlpIX0CvECN5o1oZtA16PkAb7GYiwYw%3D' const pskDecoded = 'BNlxfE2WBF7LrlpIX0CvECN5o1oZtA16PkAb7GYiwYw=' + const ownerOrbitDbIdentity = 'testOwnerOrbitDbIdentity' it('retrieves invitation code from argv', () => { const expectedCodes: InvitationData = { @@ -24,6 +25,7 @@ describe('Invitation code helper', () => { { peerId: peerId2, onionAddress: address2 }, ], psk: pskDecoded, + ownerOrbitDbIdentity, } const result = argvInvitationCode([ 'something', @@ -55,6 +57,7 @@ describe('Invitation code helper', () => { { peerId: 'peerID2', onionAddress: 'address2' }, ], psk: pskDecoded, + ownerOrbitDbIdentity, }) ).toEqual(`quiet://?peerID1=address1&peerID2=address2&${PSK_PARAM_KEY}=${psk}`) }) @@ -66,6 +69,7 @@ describe('Invitation code helper', () => { { peerId: 'peerID2', onionAddress: 'address2' }, ], psk: pskDecoded, + ownerOrbitDbIdentity, } const expected = `${QUIET_JOIN_PAGE}#peerID1=address1&peerID2=address2&${PSK_PARAM_KEY}=${psk}` expect(composeInvitationShareUrl(pairs)).toEqual(expected) @@ -77,7 +81,7 @@ describe('Invitation code helper', () => { 'invalidAddress', '/dns4/somethingElse.onion/tcp/443/wss/p2p/QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSA', ] - expect(invitationShareUrl(peerList, pskDecoded)).toEqual( + expect(invitationShareUrl(peerList, pskDecoded, ownerOrbitDbIdentity)).toEqual( `${QUIET_JOIN_PAGE}#QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSE=gloao6h5plwjy4tdlze24zzgcxll6upq2ex2fmu2ohhyu4gtys4nrjad&QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSA=somethingElse&${PSK_PARAM_KEY}=${psk}` ) }) @@ -92,6 +96,7 @@ describe('Invitation code helper', () => { { peerId: peerId2, onionAddress: address2 }, ], psk: pskDecoded, + ownerOrbitDbIdentity, }) }) diff --git a/packages/common/src/invitationCode.ts b/packages/common/src/invitationCode.ts index 10ecf79dd9..470fb6536e 100644 --- a/packages/common/src/invitationCode.ts +++ b/packages/common/src/invitationCode.ts @@ -5,6 +5,7 @@ import Logger from './logger' const logger = Logger('invite') export const PSK_PARAM_KEY = 'k' +export const OWNER_ORBIT_DB_IDENTITY_PARAM_KEY = 'o' const DEEP_URL_SCHEME_WITH_SEPARATOR = 'quiet://' const DEEP_URL_SCHEME = 'quiet' const ONION_ADDRESS_REGEX = /^[a-z0-9]{56}$/g @@ -35,16 +36,21 @@ const parseDeepUrl = ({ url, expectedProtocol = `${DEEP_URL_SCHEME}:` }: ParseDe logger.error(`Could not retrieve invitation code from deep url '${url}'`) throw new Error(`Invalid url`) } + const params = validUrl.searchParams const codes: InvitationPair[] = [] + let psk = params.get(PSK_PARAM_KEY) if (!psk) throw new Error(`No psk found in invitation code '${url}'`) - psk = decodeURIComponent(psk) if (!isPSKcodeValid(psk)) throw new Error(`Invalid psk in invitation code '${url}'`) - params.delete(PSK_PARAM_KEY) + let ownerOrbitDbIdentity = params.get(OWNER_ORBIT_DB_IDENTITY_PARAM_KEY) + if (!ownerOrbitDbIdentity) throw new Error(`No owner OrbitDB identity found in invitation code '${url}'`) + ownerOrbitDbIdentity = decodeURIComponent(ownerOrbitDbIdentity) + params.delete(OWNER_ORBIT_DB_IDENTITY_PARAM_KEY) + params.forEach((onionAddress, peerId) => { if (!peerDataValid({ peerId, onionAddress })) return codes.push({ @@ -55,7 +61,8 @@ const parseDeepUrl = ({ url, expectedProtocol = `${DEEP_URL_SCHEME}:` }: ParseDe logger('Retrieved data:', codes) return { pairs: codes, - psk: psk, + psk, + ownerOrbitDbIdentity, } } @@ -77,9 +84,10 @@ export const parseInvitationCode = (code: string): InvitationData => { /** * @arg {string[]} peers - List of peer's p2p addresses * @arg psk - Pre shared key in base64 - * @returns {string} - Complete shareable invitation link, e.g. https://tryquiet.org/join/#=&=&k= + * @returns {string} - Complete shareable invitation link, e.g. + * https://tryquiet.org/join/#=&=&k=&o= */ -export const invitationShareUrl = (peers: string[] = [], psk: string): string => { +export const invitationShareUrl = (peers: string[] = [], psk: string, ownerOrbitDbIdentity: string): string => { const pairs: InvitationPair[] = [] for (const peerAddress of peers) { let peerId: string @@ -105,7 +113,7 @@ export const invitationShareUrl = (peers: string[] = [], psk: string): string => pairs.push({ peerId: peerId, onionAddress: rawAddress }) } - return composeInvitationShareUrl({ pairs: pairs, psk: psk }) + return composeInvitationShareUrl({ pairs, psk, ownerOrbitDbIdentity }) } export const pairsToP2pAddresses = (pairs: InvitationPair[]): string[] => { @@ -130,6 +138,7 @@ const composeInvitationUrl = (baseUrl: string, data: InvitationData): string => url.searchParams.append(pair.peerId, pair.onionAddress) } url.searchParams.append(PSK_PARAM_KEY, data.psk) + url.searchParams.append(OWNER_ORBIT_DB_IDENTITY_PARAM_KEY, data.ownerOrbitDbIdentity) return url.href } diff --git a/packages/common/src/tests.ts b/packages/common/src/tests.ts index 3caa9ebd51..c3d3bb0203 100644 --- a/packages/common/src/tests.ts +++ b/packages/common/src/tests.ts @@ -11,6 +11,7 @@ export const validInvitationCodeTestData: InvitationData[] = [ }, ], psk: 'BNlxfE2WBF7LrlpIX0CvECN5o1oZtA16PkAb7GYiwYw=', + ownerOrbitDbIdentity: 'testOrbitDbIdentity1', }, { pairs: [ @@ -20,6 +21,7 @@ export const validInvitationCodeTestData: InvitationData[] = [ }, ], psk: '5T9GBVpDoRpKJQK4caDTz5e5nym2zprtoySL2oLrzr4=', + ownerOrbitDbIdentity: 'testOrbitDbIdentity2', }, ] diff --git a/packages/desktop/src/main/main.ts b/packages/desktop/src/main/main.ts index 24174c5dd9..5ef16ab0e9 100644 --- a/packages/desktop/src/main/main.ts +++ b/packages/desktop/src/main/main.ts @@ -150,8 +150,8 @@ app.on('open-url', (event, url) => { if (mainWindow) { invitationUrl = null try { - const invitationCode = parseInvitationCodeDeepUrl(url) - processInvitationCode(mainWindow, invitationCode) + const invitationData = parseInvitationCodeDeepUrl(url) + processInvitationCode(mainWindow, invitationData) } catch (e) { console.warn(e.message) } @@ -484,8 +484,8 @@ app.on('ready', async () => { } if (process.platform === 'darwin' && invitationUrl) { try { - const invitationCode = parseInvitationCodeDeepUrl(invitationUrl) - processInvitationCode(mainWindow, invitationCode) + const invitationData = parseInvitationCodeDeepUrl(invitationUrl) + processInvitationCode(mainWindow, invitationData) } catch (e) { console.warn(e.message) } finally { diff --git a/packages/desktop/src/renderer/components/CreateJoinCommunity/JoinCommunity/JoinCommunity.tsx b/packages/desktop/src/renderer/components/CreateJoinCommunity/JoinCommunity/JoinCommunity.tsx index 9dd23ee7aa..d4a63352ab 100644 --- a/packages/desktop/src/renderer/components/CreateJoinCommunity/JoinCommunity/JoinCommunity.tsx +++ b/packages/desktop/src/renderer/components/CreateJoinCommunity/JoinCommunity/JoinCommunity.tsx @@ -43,6 +43,7 @@ const JoinCommunity = () => { ownership: CommunityOwnership.User, peers: data.pairs, psk: data.psk, + ownerOrbitDbIdentity: data.ownerOrbitDbIdentity, } dispatch(communities.actions.createNetwork(payload)) } diff --git a/packages/desktop/src/renderer/components/CreateJoinCommunity/PerformCommunityActionComponent.tsx b/packages/desktop/src/renderer/components/CreateJoinCommunity/PerformCommunityActionComponent.tsx index 144a3b2a9e..400a166777 100644 --- a/packages/desktop/src/renderer/components/CreateJoinCommunity/PerformCommunityActionComponent.tsx +++ b/packages/desktop/src/renderer/components/CreateJoinCommunity/PerformCommunityActionComponent.tsx @@ -139,6 +139,7 @@ export interface PerformCommunityActionProps { handleClickInputReveal?: () => void invitationCode?: InvitationPair[] psk?: string + ownerOrbitDbIdentity?: string } export const PerformCommunityActionComponent: React.FC = ({ @@ -154,6 +155,7 @@ export const PerformCommunityActionComponent: React.FC { const [formSent, setFormSent] = useState(false) @@ -218,10 +220,14 @@ export const PerformCommunityActionComponent: React.FC { - if (communityOwnership === CommunityOwnership.User && invitationCode?.length && psk) { + if (communityOwnership === CommunityOwnership.User && invitationCode?.length && psk && ownerOrbitDbIdentity) { setFormSent(true) - setValue('name', composeInvitationShareUrl({ pairs: invitationCode, psk: psk })) + setValue('name', composeInvitationShareUrl({ pairs: invitationCode, psk, ownerOrbitDbIdentity })) } }, [communityOwnership, invitationCode]) diff --git a/packages/desktop/src/renderer/components/Settings/Settings.stories.tsx b/packages/desktop/src/renderer/components/Settings/Settings.stories.tsx index 80e8663143..ab0a4c0677 100644 --- a/packages/desktop/src/renderer/components/Settings/Settings.stories.tsx +++ b/packages/desktop/src/renderer/components/Settings/Settings.stories.tsx @@ -24,6 +24,7 @@ const invitationLink = composeInvitationShareUrl({ }, ], psk: '12345', + ownerOrbitDbIdentity: 'testOwnerOrbitDbIdentity', }) const Template: ComponentStory = args => { diff --git a/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.component.test.tsx b/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.component.test.tsx index a258ee8331..2a82f67823 100644 --- a/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.component.test.tsx +++ b/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.component.test.tsx @@ -26,6 +26,7 @@ describe('CopyLink', () => { }, ], psk: '123435', + ownerOrbitDbIdentity: 'testOwnerOrbitDbIdentity', }) const result = renderComponent( @@ -135,6 +136,7 @@ describe('CopyLink', () => { }, ], psk: '12345', + ownerOrbitDbIdentity: 'testOwnerOrbitDbIdentity', }) const result = renderComponent( diff --git a/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.stories.tsx b/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.stories.tsx index 95849b7ca6..69bc0a37e5 100644 --- a/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.stories.tsx +++ b/packages/desktop/src/renderer/components/Settings/Tabs/Invite/Invite.stories.tsx @@ -30,6 +30,7 @@ const invitationLink = composeInvitationShareUrl({ }, ], psk: '12345', + ownerOrbitDbIdentity: 'testOwnerOrbitDbIdentity', }) const args: InviteComponentProps = { invitationLink: invitationLink, diff --git a/packages/desktop/src/renderer/components/Settings/Tabs/QRCode/QRCode.stories.tsx b/packages/desktop/src/renderer/components/Settings/Tabs/QRCode/QRCode.stories.tsx index 3eee7762eb..4e25377a0d 100644 --- a/packages/desktop/src/renderer/components/Settings/Tabs/QRCode/QRCode.stories.tsx +++ b/packages/desktop/src/renderer/components/Settings/Tabs/QRCode/QRCode.stories.tsx @@ -17,6 +17,7 @@ const invitationLink = composeInvitationShareUrl({ }, ], psk: '12345', + ownerOrbitDbIdentity: 'testOwnerOrbitDbIdentity', }) const Template: ComponentStory = args => { diff --git a/packages/desktop/src/renderer/sagas/invitation/customProtocol.saga.test.ts b/packages/desktop/src/renderer/sagas/invitation/customProtocol.saga.test.ts index d26c642c5c..ed807433aa 100644 --- a/packages/desktop/src/renderer/sagas/invitation/customProtocol.saga.test.ts +++ b/packages/desktop/src/renderer/sagas/invitation/customProtocol.saga.test.ts @@ -77,6 +77,7 @@ describe('Handle invitation code', () => { communities.actions.customProtocol({ pairs: [], psk: '12345', + ownerOrbitDbIdentity: 'testOwnerOrbitDbIdentity', }) ) .withState(store.getState()) @@ -105,6 +106,7 @@ describe('Handle invitation code', () => { communities.actions.customProtocol({ pairs: validInvitationData.pairs, psk: '', + ownerOrbitDbIdentity: 'testOwnerOrbitDbIdentity', }) ) .withState(store.getState()) diff --git a/packages/desktop/src/renderer/sagas/invitation/customProtocol.saga.ts b/packages/desktop/src/renderer/sagas/invitation/customProtocol.saga.ts index f6e49ea674..98a26e3035 100644 --- a/packages/desktop/src/renderer/sagas/invitation/customProtocol.saga.ts +++ b/packages/desktop/src/renderer/sagas/invitation/customProtocol.saga.ts @@ -31,11 +31,12 @@ export function* customProtocolSaga( return } const invitationData = action.payload - if (invitationData && invitationData.pairs.length > 0 && invitationData.psk) { + if (invitationData && invitationData.pairs.length > 0 && invitationData.psk && invitationData.ownerOrbitDbIdentity) { const payload: CreateNetworkPayload = { ownership: CommunityOwnership.User, peers: invitationData.pairs, psk: invitationData.psk, + ownerOrbitDbIdentity: invitationData.ownerOrbitDbIdentity, } yield* put(communities.actions.createNetwork(payload)) } else { diff --git a/packages/desktop/src/rtl-tests/community.join.test.tsx b/packages/desktop/src/rtl-tests/community.join.test.tsx index 74a0b06e8b..7bda819e0e 100644 --- a/packages/desktop/src/rtl-tests/community.join.test.tsx +++ b/packages/desktop/src/rtl-tests/community.join.test.tsx @@ -52,6 +52,7 @@ describe('User', () => { }, ], psk: 'BNlxfE2WBF7LrlpIX0CvECN5o1oZtA16PkAb7GYiwYw=', + ownerOrbitDbIdentity: 'testOrbitDbIdentity', } const validCode = composeInvitationShareUrl(validData) // trigger diff --git a/packages/desktop/src/rtl-tests/customProtocol.test.tsx b/packages/desktop/src/rtl-tests/customProtocol.test.tsx index ead55826de..cfafd7e160 100644 --- a/packages/desktop/src/rtl-tests/customProtocol.test.tsx +++ b/packages/desktop/src/rtl-tests/customProtocol.test.tsx @@ -68,6 +68,7 @@ describe('Opening app through custom protocol', () => { const invitationCodes: InvitationData = { pairs: [{ peerId: 'abcdef', onionAddress: 'bidrmzr3ee6qa2vvrlcnqvvvsk2gmjktcqkunba326parszr44gibwyd' }], psk: '12345', + ownerOrbitDbIdentity: 'testOwnerOrbitDbIdentity', } store.dispatch(communities.actions.customProtocol(invitationCodes)) diff --git a/packages/identity/src/createUserCert.ts b/packages/identity/src/createUserCert.ts index a9e8034cb3..d8e53b4837 100644 --- a/packages/identity/src/createUserCert.ts +++ b/packages/identity/src/createUserCert.ts @@ -29,7 +29,7 @@ export const createUserCert = async ( notAfterDate: Date ): Promise => { const { hashAlg, signAlg } = config - const userCertificate = await generateuserCertificate({ + const userCertificate = await generateUserCertificate({ issuerCert: loadCertificate(rootCA), issuerKey: await loadPrivateKey(rootKey, signAlg), pkcs10: await loadCSR(userCsr), @@ -45,7 +45,7 @@ export const createUserCert = async ( } } -async function generateuserCertificate({ +async function generateUserCertificate({ issuerCert, issuerKey, pkcs10, diff --git a/packages/mobile/src/screens/JoinCommunity/JoinCommunity.screen.tsx b/packages/mobile/src/screens/JoinCommunity/JoinCommunity.screen.tsx index a925ed2ba7..381d6831af 100644 --- a/packages/mobile/src/screens/JoinCommunity/JoinCommunity.screen.tsx +++ b/packages/mobile/src/screens/JoinCommunity/JoinCommunity.screen.tsx @@ -40,6 +40,7 @@ export const JoinCommunityScreen: FC = ({ route }) => ownership: CommunityOwnership.User, peers: data.pairs, psk: data.psk, + ownerOrbitDbIdentity: data.ownerOrbitDbIdentity, } dispatch(communities.actions.createNetwork(payload)) dispatch( diff --git a/packages/mobile/src/store/init/deepLink/deepLink.saga.test.ts b/packages/mobile/src/store/init/deepLink/deepLink.saga.test.ts index e6218b7de9..abd7b77c9b 100644 --- a/packages/mobile/src/store/init/deepLink/deepLink.saga.test.ts +++ b/packages/mobile/src/store/init/deepLink/deepLink.saga.test.ts @@ -77,6 +77,7 @@ describe('deepLinkSaga', () => { ownership: CommunityOwnership.User, peers: validData.pairs, psk: validData.psk, + ownerOrbitDbIdentity: validData.ownerOrbitDbIdentity, }) ) .run() @@ -113,6 +114,7 @@ describe('deepLinkSaga', () => { ownership: CommunityOwnership.User, peers: validData.pairs, psk: validData.psk, + ownerOrbitDbIdentity: validData.ownerOrbitDbIdentity, }) ) .run() @@ -150,6 +152,7 @@ describe('deepLinkSaga', () => { ownership: CommunityOwnership.User, peers: validData.pairs, psk: validData.psk, + ownerOrbitDbIdentity: validData.ownerOrbitDbIdentity, }) ) .run() @@ -164,6 +167,7 @@ describe('deepLinkSaga', () => { }, ], psk: 'BNlxfE=', + ownerOrbitDbIdentity: 'testId', } const invalidCode = composeInvitationShareUrl(invalidData) store.dispatch( @@ -193,6 +197,7 @@ describe('deepLinkSaga', () => { ownership: CommunityOwnership.User, peers: validData.pairs, psk: validData.psk, + ownerOrbitDbIdentity: validData.ownerOrbitDbIdentity, }) ) .run() @@ -234,6 +239,7 @@ describe('deepLinkSaga', () => { ownership: CommunityOwnership.User, peers: validData.pairs, psk: validData.psk, + ownerOrbitDbIdentity: validData.ownerOrbitDbIdentity, }) ) .run() diff --git a/packages/mobile/src/store/init/deepLink/deepLink.saga.ts b/packages/mobile/src/store/init/deepLink/deepLink.saga.ts index 5228b617b9..3420fb198d 100644 --- a/packages/mobile/src/store/init/deepLink/deepLink.saga.ts +++ b/packages/mobile/src/store/init/deepLink/deepLink.saga.ts @@ -80,6 +80,7 @@ export function* deepLinkSaga(action: PayloadAction { ), ] const psk = '12345' + const ownerOrbitDbIdentity = 'testOwnerOrbitDbIdentity' await factory.create['payload']>('Community', { peerList, + ownerOrbitDbIdentity, }) store.dispatch(communitiesActions.savePSK(psk)) const selectorInvitationUrl = communitiesSelectors.invitationUrl(store.getState()) - const expectedUrl = invitationShareUrl(peerList, psk) + const expectedUrl = invitationShareUrl(peerList, psk, ownerOrbitDbIdentity) expect(expectedUrl).not.toEqual('') expect(selectorInvitationUrl).toEqual(expectedUrl) }) diff --git a/packages/state-manager/src/sagas/communities/communities.selectors.ts b/packages/state-manager/src/sagas/communities/communities.selectors.ts index f0e7113803..4ac29c8388 100644 --- a/packages/state-manager/src/sagas/communities/communities.selectors.ts +++ b/packages/state-manager/src/sagas/communities/communities.selectors.ts @@ -61,14 +61,24 @@ export const psk = createSelector(communitiesSlice, reducerState => { return reducerState.psk }) -export const invitationUrl = createSelector(currentCommunity, psk, (community, communityPsk) => { - const peerList = community?.peerList - if (!peerList || peerList?.length === 0) return '' - if (!communityPsk) return '' - const initialPeers = peerList.slice(0, 4) - return invitationShareUrl(initialPeers, communityPsk) +export const ownerOrbitDbIdentity = createSelector(currentCommunity, currentCommunity => { + return currentCommunity?.ownerOrbitDbIdentity }) +export const invitationUrl = createSelector( + currentCommunity, + psk, + ownerOrbitDbIdentity, + (community, communityPsk, ownerOrbitDbIdentity) => { + const peerList = community?.peerList + if (!peerList || peerList?.length === 0) return '' + if (!communityPsk) return '' + if (!ownerOrbitDbIdentity) return '' + const initialPeers = peerList.slice(0, 3) + return invitationShareUrl(initialPeers, communityPsk, ownerOrbitDbIdentity) + } +) + export const ownerNickname = createSelector( currentCommunity, getOldestParsedCerificate, @@ -105,4 +115,5 @@ export const communitiesSelectors = { invitationUrl, ownerNickname, psk, + ownerOrbitDbIdentity, } diff --git a/packages/state-manager/src/sagas/communities/communities.slice.ts b/packages/state-manager/src/sagas/communities/communities.slice.ts index e070e21023..63ef8764a3 100644 --- a/packages/state-manager/src/sagas/communities/communities.slice.ts +++ b/packages/state-manager/src/sagas/communities/communities.slice.ts @@ -9,9 +9,8 @@ import { type ResponseCreateNetworkPayload, type ResponseRegistrarPayload, type StorePeerListPayload, - type UpdateCommunityPayload, type UpdateRegistrationAttemptsPayload, - CommunityMetadataPayload, + CommunityMetadata, InvitationData, } from '@quiet/types' @@ -32,7 +31,7 @@ export const communitiesSlice = createSlice({ addNewCommunity: (state, action: PayloadAction) => { communitiesAdapter.addOne(state.communities, action.payload) }, - updateCommunity: (state, _action: PayloadAction) => state, + updateCommunity: (state, _action: PayloadAction) => state, updateCommunityData: (state, action: PayloadAction) => { communitiesAdapter.updateOne(state.communities, { id: action.payload.id, @@ -87,7 +86,7 @@ export const communitiesSlice = createSlice({ }, }) }, - saveCommunityMetadata: (state, _action: PayloadAction) => state, + saveCommunityMetadata: (state, _action: PayloadAction) => state, savePSK: (state, action: PayloadAction) => { state.psk = action.payload }, diff --git a/packages/state-manager/src/sagas/communities/communities.types.ts b/packages/state-manager/src/sagas/communities/communities.types.ts index bc4d87a589..e6f97b9979 100644 --- a/packages/state-manager/src/sagas/communities/communities.types.ts +++ b/packages/state-manager/src/sagas/communities/communities.types.ts @@ -35,11 +35,6 @@ export interface InitCommunityPayload { peers?: string[] } -export interface UpdateCommunityPayload { - id: string - rootCa: string -} - export interface LaunchRegistrarPayload { id: string peerId: string diff --git a/packages/state-manager/src/sagas/communities/createNetwork/createNetwork.saga.ts b/packages/state-manager/src/sagas/communities/createNetwork/createNetwork.saga.ts index 157173bd0b..544af5a991 100644 --- a/packages/state-manager/src/sagas/communities/createNetwork/createNetwork.saga.ts +++ b/packages/state-manager/src/sagas/communities/createNetwork/createNetwork.saga.ts @@ -34,6 +34,7 @@ export function* createNetworkSaga( CA, rootCa: CA?.rootCertString, psk: action.payload.psk, + ownerOrbitDbIdentity: action.payload.ownerOrbitDbIdentity, } const invitationPeers = action.payload.peers diff --git a/packages/state-manager/src/sagas/communities/saveCommunityMetadata/saveCommunityMetadata.saga.ts b/packages/state-manager/src/sagas/communities/saveCommunityMetadata/saveCommunityMetadata.saga.ts index 54c782ddf3..86857d83a6 100644 --- a/packages/state-manager/src/sagas/communities/saveCommunityMetadata/saveCommunityMetadata.saga.ts +++ b/packages/state-manager/src/sagas/communities/saveCommunityMetadata/saveCommunityMetadata.saga.ts @@ -15,6 +15,7 @@ export function* saveCommunityMetadataSaga( communitiesActions.updateCommunity({ id: communityId, rootCa: action.payload.rootCa, + ownerOrbitDbIdentity: action.payload.ownerOrbitDbIdentity, }) ) yield* put( diff --git a/packages/state-manager/src/sagas/communities/updateCommunity/updateCommunity.saga.ts b/packages/state-manager/src/sagas/communities/updateCommunity/updateCommunity.saga.ts index 70befbaff2..e2845230c6 100644 --- a/packages/state-manager/src/sagas/communities/updateCommunity/updateCommunity.saga.ts +++ b/packages/state-manager/src/sagas/communities/updateCommunity/updateCommunity.saga.ts @@ -1,23 +1,40 @@ -import { CertFieldsTypes, getCertFieldValue, loadCertificate } from '@quiet/identity' import { call, put } from 'typed-redux-saga' -import { communitiesActions } from '../communities.slice' +import { type Certificate } from 'pkijs' + +import { CertFieldsTypes, getCertFieldValue, loadCertificate } from '@quiet/identity' import { type PayloadAction } from '@reduxjs/toolkit' +import { communitiesActions } from '../communities.slice' + export function* updateCommunitySaga( action: PayloadAction['payload']> ): Generator { - const rootCa = loadCertificate(action.payload.rootCa) + let rootCa: Certificate + let communityName: string | null = null + + if (action.payload.rootCa) { + rootCa = loadCertificate(action.payload.rootCa) + communityName = yield* call(getCertFieldValue, rootCa, CertFieldsTypes.commonName) - const communityName = yield* call(getCertFieldValue, rootCa, CertFieldsTypes.commonName) - if (!communityName) { - console.error(`Could not retrieve ${CertFieldsTypes.commonName} from rootca`) - return + if (!communityName) { + console.error(`Could not retrieve ${CertFieldsTypes.commonName} from rootca`) + } } - const payload = { + const payload: { id: string; name?: string; rootCa?: string; ownerOrbitDbIdentity?: string } = { id: action.payload.id, - rootCa: action.payload.rootCa, - name: communityName, + } + + if (communityName) { + payload.name = communityName + } + + if (action.payload.rootCa) { + payload.rootCa = action.payload.rootCa + } + + if (action.payload.ownerOrbitDbIdentity) { + payload.ownerOrbitDbIdentity = action.payload.ownerOrbitDbIdentity } yield* put(communitiesActions.updateCommunityData(payload)) diff --git a/packages/state-manager/src/sagas/identity/registerUsername/registerUsername.saga.test.ts b/packages/state-manager/src/sagas/identity/registerUsername/registerUsername.saga.test.ts index 2fdae61e2c..829d1e1a96 100644 --- a/packages/state-manager/src/sagas/identity/registerUsername/registerUsername.saga.test.ts +++ b/packages/state-manager/src/sagas/identity/registerUsername/registerUsername.saga.test.ts @@ -27,6 +27,7 @@ describe('registerUsernameSaga', () => { { CA: null, rootCa: 'rootCertString', + ownerOrbitDbIdentity: 'ownerOrbitDbId', } ) @@ -68,6 +69,7 @@ describe('registerUsernameSaga', () => { CA: community.CA, rootCa: undefined, psk: psk, + ownerOrbitDbIdentity: 'ownerOrbitDbId', }, ]) .dispatch(identityActions.addNewIdentity(identity)) diff --git a/packages/state-manager/src/sagas/identity/registerUsername/registerUsername.saga.ts b/packages/state-manager/src/sagas/identity/registerUsername/registerUsername.saga.ts index 7a97456494..c636a3fc03 100644 --- a/packages/state-manager/src/sagas/identity/registerUsername/registerUsername.saga.ts +++ b/packages/state-manager/src/sagas/identity/registerUsername/registerUsername.saga.ts @@ -22,6 +22,10 @@ export function* registerUsernameSaga( console.error('Could not register username, no community data') return } + + // Is there another way to reorganize the following code? Can we + // emit the CREATE_NETWORK event in the createNetworkSaga? + const psk = yield* select(communitiesSelectors.psk) const networkPayload: Community = { id: community.id, @@ -30,6 +34,7 @@ export function* registerUsernameSaga( CA: community.CA, rootCa: community.CA?.rootCertString, psk: psk, + ownerOrbitDbIdentity: community.ownerOrbitDbIdentity, } if (!isUsernameTaken) { diff --git a/packages/state-manager/src/sagas/socket/startConnection/startConnection.saga.ts b/packages/state-manager/src/sagas/socket/startConnection/startConnection.saga.ts index 55d7ffeaba..0f3bbdc34e 100644 --- a/packages/state-manager/src/sagas/socket/startConnection/startConnection.saga.ts +++ b/packages/state-manager/src/sagas/socket/startConnection/startConnection.saga.ts @@ -195,7 +195,12 @@ export function subscribe(socket: Socket) { }) // Errors socket.on(SocketActionTypes.ERROR, (payload: ErrorPayload) => { - log(payload) + // FIXME: It doesn't look like log errors have the red error + // color in the console, which makes them difficult to find. + // Also when only printing the payload, the full trace is not + // available. + log.error(payload) + console.error(payload, payload.trace) emit(errorsActions.handleError(payload)) }) // Certificates @@ -251,14 +256,9 @@ export function subscribe(socket: Socket) { ) emit(identityActions.savedOwnerCertificate(payload.communityId)) }) - socket.on(SocketActionTypes.SAVE_COMMUNITY_METADATA, (payload: CommunityMetadata) => { - log(`${SocketActionTypes.SAVE_COMMUNITY_METADATA}: ${payload}`) - emit( - communitiesActions.saveCommunityMetadata({ - rootCa: payload.rootCa, - ownerCertificate: payload.ownerCertificate, - }) - ) + socket.on(SocketActionTypes.COMMUNITY_METADATA_SAVED, (payload: CommunityMetadata) => { + log(`${SocketActionTypes.COMMUNITY_METADATA_SAVED}: ${payload}`) + emit(communitiesActions.saveCommunityMetadata(payload)) }) socket.on(SocketActionTypes.LIBP2P_PSK_SAVED, (payload: { psk: string }) => { log(`${SocketActionTypes.LIBP2P_PSK_SAVED}`) diff --git a/packages/state-manager/src/utils/functions/invitationCode/invitationCode.test.ts b/packages/state-manager/src/utils/functions/invitationCode/invitationCode.test.ts index ecdf76ea35..53c694388b 100644 --- a/packages/state-manager/src/utils/functions/invitationCode/invitationCode.test.ts +++ b/packages/state-manager/src/utils/functions/invitationCode/invitationCode.test.ts @@ -1,5 +1,5 @@ import { getInvitationCodes } from './invitationCode' -import { PSK_PARAM_KEY, QUIET_JOIN_PAGE } from '@quiet/common' +import { OWNER_ORBIT_DB_IDENTITY_PARAM_KEY, PSK_PARAM_KEY, QUIET_JOIN_PAGE } from '@quiet/common' describe('Invitation code helper', () => { const peerId1 = 'QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSA' @@ -7,11 +7,13 @@ describe('Invitation code helper', () => { const peerId2 = 'QmZoiJNAvCffeEHBjk766nLuKVdkxkAT7wfFJDPPLsbKSE' const address2 = 'y7yczmugl2tekami7sbdz5pfaemvx7bahwthrdvcbzw5vex2crsr26qd' const psk = 'BNlxfE2WBF7LrlpIX0CvECN5o1oZtA16PkAb7GYiwYw=' + const ownerOrbitDbIdentity = 'testOwnerOrbitDbIdentity' const encodedPsk = encodeURIComponent(psk) + const encodedOwnerOrbitDbIdentity = encodeURIComponent(ownerOrbitDbIdentity) it('retrieves invitation code if url is a proper share url', () => { const result = getInvitationCodes( - `${QUIET_JOIN_PAGE}#${peerId1}=${address1}&${peerId2}=${address2}&${PSK_PARAM_KEY}=${encodedPsk}` + `${QUIET_JOIN_PAGE}#${peerId1}=${address1}&${peerId2}=${address2}&${PSK_PARAM_KEY}=${encodedPsk}&${OWNER_ORBIT_DB_IDENTITY_PARAM_KEY}=${encodedOwnerOrbitDbIdentity}` ) expect(result).toEqual({ pairs: [ @@ -19,6 +21,7 @@ describe('Invitation code helper', () => { { peerId: peerId2, onionAddress: address2 }, ], psk, + ownerOrbitDbIdentity, }) }) @@ -35,24 +38,26 @@ describe('Invitation code helper', () => { }) it('retrieves invitation code if url is a proper code', () => { - const result = getInvitationCodes(`${peerId1}=${address1}&${peerId2}=${address2}&${PSK_PARAM_KEY}=${encodedPsk}`) + const result = getInvitationCodes(`${peerId1}=${address1}&${peerId2}=${address2}&${PSK_PARAM_KEY}=${encodedPsk}&${OWNER_ORBIT_DB_IDENTITY_PARAM_KEY}=${encodedOwnerOrbitDbIdentity}`) expect(result).toEqual({ pairs: [ { peerId: peerId1, onionAddress: address1 }, { peerId: peerId2, onionAddress: address2 }, ], psk, + ownerOrbitDbIdentity, }) }) it('retrieves invitation code if url is a proper code', () => { - const result = getInvitationCodes(`${peerId1}=${address1}&${peerId2}=${address2}&${PSK_PARAM_KEY}=${encodedPsk}`) + const result = getInvitationCodes(`${peerId1}=${address1}&${peerId2}=${address2}&${PSK_PARAM_KEY}=${encodedPsk}&${OWNER_ORBIT_DB_IDENTITY_PARAM_KEY}=${encodedOwnerOrbitDbIdentity}`) expect(result).toEqual({ pairs: [ { peerId: peerId1, onionAddress: address1 }, { peerId: peerId2, onionAddress: address2 }, ], psk, + ownerOrbitDbIdentity, }) }) }) diff --git a/packages/types/src/community.ts b/packages/types/src/community.ts index 06fb3daa8c..fbf3017c58 100644 --- a/packages/types/src/community.ts +++ b/packages/types/src/community.ts @@ -21,6 +21,7 @@ export interface Community { registrationAttempts?: number ownerCertificate?: string psk?: string + ownerOrbitDbIdentity?: string } export enum CommunityOwnership { @@ -38,6 +39,7 @@ export interface CreateNetworkPayload { name?: string peers?: InvitationPair[] psk?: string + ownerOrbitDbIdentity?: string } export interface ResponseCreateNetworkPayload { @@ -59,11 +61,6 @@ export interface InitCommunityPayload { peers?: string[] } -export interface UpdateCommunityPayload { - id: string - rootCa: string -} - export interface LaunchRegistrarPayload { id: string peerId: string @@ -108,11 +105,10 @@ export interface AddOwnerCertificatePayload { export interface CommunityMetadata { id: string + // Perhaps we should rename this to rootCertificate? When I think of + // certificate authority, I think of the owner themselves. rootCa: string ownerCertificate: string -} - -export interface CommunityMetadataPayload { - rootCa: string - ownerCertificate: string + // Owner's OrbitDB identity + ownerOrbitDbIdentity?: string } diff --git a/packages/types/src/errors.ts b/packages/types/src/errors.ts index 791a59a0fc..ede9de81f9 100644 --- a/packages/types/src/errors.ts +++ b/packages/types/src/errors.ts @@ -5,6 +5,7 @@ export interface ErrorPayload { code?: number message?: string community?: string + trace?: string } export enum ErrorTypes { diff --git a/packages/types/src/network.ts b/packages/types/src/network.ts index 3e475cbdf5..894ca4f427 100644 --- a/packages/types/src/network.ts +++ b/packages/types/src/network.ts @@ -11,4 +11,5 @@ export type InvitationPair = { export type InvitationData = { pairs: InvitationPair[] psk: string + ownerOrbitDbIdentity: string } diff --git a/packages/types/src/socket.ts b/packages/types/src/socket.ts index 3612a77a9a..97aab89c66 100644 --- a/packages/types/src/socket.ts +++ b/packages/types/src/socket.ts @@ -55,7 +55,6 @@ export enum SocketActionTypes { SAVE_OWNER_CERTIFICATE = 'saveOwnerCertificate', SAVED_OWNER_CERTIFICATE = 'savedOwnerCertificate', SAVE_USER_CSR = 'saveUserCsr', - SAVE_COMMUNITY_METADATA = 'saveCommunityMetadata', SAVED_USER_CSR = 'savedUserCsr', SEND_DIRECT_MESSAGE = 'sendDirectMessage', SEND_MESSAGE = 'sendMessage', @@ -63,6 +62,7 @@ export enum SocketActionTypes { SEND_PEER_ID = 'sendPeerId', SEND_USER_CERTIFICATE = 'sendUserCertificate', SEND_COMMUNITY_METADATA = 'sendCommunityMetadata', + COMMUNITY_METADATA_SAVED = 'communityMetadataSaved', SUBSCRIBE_FOR_ALL_CONVERSATIONS = 'subscribeToAllConversations', SUBSCRIBE_FOR_DIRECT_MESSAGE_THREAD = 'subscribeToDirectMessageThread', // T