From a7a7ac03160a00455470145410770ac75780c0f0 Mon Sep 17 00:00:00 2001 From: eugenvoronov <104138627+eugenvoronov@users.noreply.github.com> Date: Mon, 22 May 2023 18:05:15 +0300 Subject: [PATCH] Fortune v2 (#487) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Added Exchange Oracle basic template * Added basic templates for all services with migrations and typeorm entities * Change the provider of the fiat section * Clean logs * use minio for python sdk doctest (#281) * fix duplicated dependency * Added oracles, added new packages, updated orm config * Job launcher/fiat payments (#333) * Added payment service logic. Added job services base template * Finalized payment module implementation. Added fortune and cvat job types * Fixed payment module dto. Fixed jwt public guard * Updated required node version to 18.x * Job launcher/job types (#336) * Added logic to process both types of job, Fortune and CVAT * Implemented support for both types of jobs Fortune and CVAT * Updated job migrations. Updated dto types. Tested job creation logic * Job launcher/job types (#337) * Added logic to process both types of job, Fortune and CVAT * Implemented support for both types of jobs Fortune and CVAT * Updated job migrations. Updated dto types. Tested job creation logic * Added untracked files * Implemented encryption module (#339) * Change enums to specific folder and add currency service * Job launcher/encrypt manifest (#341) * Updated storage service. Updated create job and manifest encryption logic * Updated readme * Removed .github and assets folder * Job launcher/encrypt manifest (#341) * Updated storage service. Updated create job and manifest encryption logic * Updated readme * Removed .github and assets folder * Delete contracts folder and create currency controller * Change function name * Add docker compose with minio and postgres services * Update fortune v2 project name * Added webhook incomming logic processing (#355) * Added webhook incomming logic processing. Updated payment scheme * Added pending incoming webhook processing with cron * Added user balance logic (#357) * Recording oracle/webhook (#358) * Added basic notification service for oracle * Fixed typos * Added base webhook module (#359) * Added oracle client (#360) * Refactored job launcher * Removed oracles services * Updated dto * Refactored service * Moved mogrations * Added cockie parser * Resolved PRs comments --------- Co-authored-by: Francisco López Co-authored-by: CryptoRush <98655210+leric7@users.noreply.github.com> Co-authored-by: Eric Lee Co-authored-by: Francisco López <50665615+flopez7@users.noreply.github.com> --- .gitignore | 3 + .../examples/fortune-v2/docker-compose.yml | 47 + .../job-launcher/server/.env.example | 21 + .../job-launcher/server/.eslintignore | 11 + .../fortune-v2/job-launcher/server/.eslintrc | 9 + .../fortune-v2/job-launcher/server/.gitignore | 45 + .../fortune-v2/job-launcher/server/.huskyrc | 5 + .../job-launcher/server/.prettierrc | 7 + .../fortune-v2/job-launcher/server/LICENSE | 21 + .../fortune-v2/job-launcher/server/README.md | 66 + .../job-launcher/server/jest.config.json | 10 + .../job-launcher/server/ormconfig.json | 16 + .../job-launcher/server/package.json | 97 ++ .../job-launcher/server/src/app.controller.ts | 13 + .../job-launcher/server/src/app.module.ts | 40 + .../server/src/common/collection/index.ts | 3 + .../src/common/collection/pagination.ts | 28 + .../server/src/common/collection/search.ts | 15 + .../server/src/common/collection/sort.ts | 27 + .../server/src/common/constants/errors.ts | 50 + .../server/src/common/constants/index.ts | 4 + .../server/src/common/decorators/base.ts | 5 + .../server/src/common/decorators/index.ts | 3 + .../server/src/common/decorators/public.ts | 3 + .../server/src/common/decorators/role.ts | 4 + .../server/src/common/decorators/user.ts | 19 + .../server/src/common/dynamic/index.ts | 145 ++ .../server/src/common/enums/user.ts | 10 + .../server/src/common/guards/index.ts | 2 + .../server/src/common/guards/jwt.http.ts | 28 + .../server/src/common/guards/roles.ts | 24 + .../server/src/common/interceptors/index.ts | 2 + .../src/common/interceptors/not-found.ts | 16 + .../src/common/interceptors/pagination.ts | 10 + .../server/src/common/pipes/index.ts | 1 + .../server/src/common/pipes/validation.ts | 21 + .../server/src/common/validators/confirm.ts | 63 + .../server/src/common/validators/index.ts | 2 + .../server/src/common/validators/password.ts | 62 + .../server/src/database/base.entity.ts | 25 + .../server/src/database/database.module.ts | 50 + .../migrations/1677845576145-addShema.ts | 14 + .../1677845804077-installExtension.ts | 13 + .../migrations/1677867973538-addUserTable.ts | 68 + .../migrations/1677867985970-addAuthTable.ts | 77 ++ .../migrations/1677867996573-addTokenTable.ts | 82 ++ .../server/src/database/typeorm/index.ts | 2 + .../database/typeorm/typeorm-logger.module.ts | 9 + .../typeorm/typeorm-logger.service.ts | 71 + .../job-launcher/server/src/main.ts | 66 + .../server/src/modules/auth/auth.dto.ts | 81 ++ .../server/src/modules/auth/auth.entity.ts | 30 + .../src/modules/auth/auth.jwt.controller.ts | 72 + .../server/src/modules/auth/auth.module.ts | 31 + .../src/modules/auth/auth.service.spec.ts | 44 + .../server/src/modules/auth/auth.service.ts | 145 ++ .../server/src/modules/auth/strategy/index.ts | 1 + .../src/modules/auth/strategy/jwt.http.ts | 34 + .../server/src/modules/auth/token.entity.ts | 36 + .../src/modules/auth/token.repository.ts | 23 + .../src/modules/health/health.controller.ts | 28 + .../src/modules/health/health.module.ts | 11 + .../src/modules/user/user.controller.ts | 19 + .../server/src/modules/user/user.dto.ts | 71 + .../server/src/modules/user/user.entity.ts | 26 + .../server/src/modules/user/user.module.ts | 17 + .../src/modules/user/user.repository.ts | 55 + .../src/modules/user/user.seed.module.ts | 13 + .../src/modules/user/user.seed.service.ts | 33 + .../src/modules/user/user.serializer.ts | 18 + .../src/modules/user/user.service.spec.ts | 92 ++ .../server/src/modules/user/user.service.ts | 85 ++ .../job-launcher/server/tsconfig.json | 29 + .../job-launcher/server/tsconfig.test.json | 7 + packages/examples/fortune-v2/package.json | 22 + yarn.lock | 1181 ++++++++++++++++- 76 files changed, 3575 insertions(+), 64 deletions(-) create mode 100644 packages/examples/fortune-v2/docker-compose.yml create mode 100644 packages/examples/fortune-v2/job-launcher/server/.env.example create mode 100644 packages/examples/fortune-v2/job-launcher/server/.eslintignore create mode 100644 packages/examples/fortune-v2/job-launcher/server/.eslintrc create mode 100644 packages/examples/fortune-v2/job-launcher/server/.gitignore create mode 100644 packages/examples/fortune-v2/job-launcher/server/.huskyrc create mode 100644 packages/examples/fortune-v2/job-launcher/server/.prettierrc create mode 100644 packages/examples/fortune-v2/job-launcher/server/LICENSE create mode 100644 packages/examples/fortune-v2/job-launcher/server/README.md create mode 100644 packages/examples/fortune-v2/job-launcher/server/jest.config.json create mode 100644 packages/examples/fortune-v2/job-launcher/server/ormconfig.json create mode 100644 packages/examples/fortune-v2/job-launcher/server/package.json create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/app.controller.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/app.module.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/collection/index.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/collection/pagination.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/collection/search.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/collection/sort.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/constants/errors.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/constants/index.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/decorators/base.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/decorators/index.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/decorators/public.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/decorators/role.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/decorators/user.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/dynamic/index.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/enums/user.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/guards/index.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/guards/jwt.http.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/guards/roles.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/interceptors/index.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/interceptors/not-found.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/interceptors/pagination.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/pipes/index.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/pipes/validation.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/validators/confirm.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/validators/index.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/common/validators/password.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/database/base.entity.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/database/database.module.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677845576145-addShema.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677845804077-installExtension.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677867973538-addUserTable.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677867985970-addAuthTable.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677867996573-addTokenTable.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/database/typeorm/index.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/database/typeorm/typeorm-logger.module.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/database/typeorm/typeorm-logger.service.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/main.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.dto.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.entity.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.jwt.controller.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.module.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.service.spec.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.service.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/auth/strategy/index.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/auth/strategy/jwt.http.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/auth/token.entity.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/auth/token.repository.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/health/health.controller.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/health/health.module.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.controller.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.dto.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.entity.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.module.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.repository.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.seed.module.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.seed.service.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.serializer.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.service.spec.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.service.ts create mode 100644 packages/examples/fortune-v2/job-launcher/server/tsconfig.json create mode 100644 packages/examples/fortune-v2/job-launcher/server/tsconfig.test.json create mode 100644 packages/examples/fortune-v2/package.json diff --git a/.gitignore b/.gitignore index 7740b04047..42529a7999 100644 --- a/.gitignore +++ b/.gitignore @@ -46,3 +46,6 @@ dist #cache cache + +#Postgres Data +db \ No newline at end of file diff --git a/packages/examples/fortune-v2/docker-compose.yml b/packages/examples/fortune-v2/docker-compose.yml new file mode 100644 index 0000000000..9e8e022824 --- /dev/null +++ b/packages/examples/fortune-v2/docker-compose.yml @@ -0,0 +1,47 @@ +version: '3.7' + +services: + postgres: + image: postgres:latest + restart: always + environment: + - POSTGRES_USER=fortune + - POSTGRES_PASSWORD=fortune + - POSTGRES_DB=hmt-job-launcher + logging: + options: + max-size: 10m + max-file: "3" + ports: + - '5432:5432' + volumes: + - ./db:/var/lib/postgresql/data + minio: + container_name: minio + image: minio/minio:RELEASE.2022-05-26T05-48-41Z + ports: + - 9001:9001 + - 9000:9000 + environment: + MINIO_ROOT_USER: dev + MINIO_ROOT_PASSWORD: devdevdev + entrypoint: 'sh' + command: + -c "minio server /data --console-address ':9001'" + healthcheck: + test: ["CMD", "curl", "-f", "http://localhost:9000/minio/health/live"] + interval: 5s + timeout: 5s + retries: 3 + minio-mc: + container_name: minio-mc + image: minio/mc + depends_on: + minio: + condition: service_healthy + entrypoint: > + /bin/sh -c " + /usr/bin/mc config host add myminio http://minio:9000 dev devdevdev; + /usr/bin/mc mb myminio/launcher; + /usr/bin/mc anonymous set public myminio/launcher; + " diff --git a/packages/examples/fortune-v2/job-launcher/server/.env.example b/packages/examples/fortune-v2/job-launcher/server/.env.example new file mode 100644 index 0000000000..2d404b9dac --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/.env.example @@ -0,0 +1,21 @@ +# General +NODE_ENV= +HOST= +PORT= +FE_URL= +SESSION_SECRET= +PASSWORD_SECRET='$2b$10$EICgM2wYixoJisgqckU9gu' + +# Database +DB_TYPE= +POSTGRES_HOST= +POSTGRES_USER= +POSTGRES_PASSWORD= +POSTGRES_DB= +POSTGRES_SYNC= +POSTGRES_PORT= + +# Auth +JWT_SECRET= +JWT_ACCESS_TOKEN_EXPIRES_IN= +JWT_REFRESH_TOKEN_EXPIRES_IN= \ No newline at end of file diff --git a/packages/examples/fortune-v2/job-launcher/server/.eslintignore b/packages/examples/fortune-v2/job-launcher/server/.eslintignore new file mode 100644 index 0000000000..7a943abfd8 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/.eslintignore @@ -0,0 +1,11 @@ +**/node_modules/* +**/dist/* +**/README.md +**/ganache/* +**/build/* +**/cache/* +**/coverage/* +**/node_modules/* +**/truffle.js +**/cache/* +**/typechain-types/* \ No newline at end of file diff --git a/packages/examples/fortune-v2/job-launcher/server/.eslintrc b/packages/examples/fortune-v2/job-launcher/server/.eslintrc new file mode 100644 index 0000000000..7f6bd3220c --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/.eslintrc @@ -0,0 +1,9 @@ +{ + "parserOptions": { + "project": "./tsconfig.test.json" + }, + "rules": { + "@typescript-eslint/explicit-module-boundary-types": "off" + }, + "root": true +} diff --git a/packages/examples/fortune-v2/job-launcher/server/.gitignore b/packages/examples/fortune-v2/job-launcher/server/.gitignore new file mode 100644 index 0000000000..738b32c326 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/.gitignore @@ -0,0 +1,45 @@ +# compiled output +dist +pgdata +/node_modules +.lintstagedrc + +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Tests +/coverage +/.nyc_output + +# IDEs and editors +/.idea + +# IDE - VSCode +.vscode/* + +# OS +.DS_Store + +# env +.env.* +.env + +# VisualStudioCode + ../.vscode/ +.vscode +.vscode/* + +# yarn +.yarn/build-state.yml +.yarn/cache +yarn-debug.log* +yarn-error.log* +.yarn/install-state.gz +.yarn-integrity +# Yarn Integrity file +.yarn/unplugged + diff --git a/packages/examples/fortune-v2/job-launcher/server/.huskyrc b/packages/examples/fortune-v2/job-launcher/server/.huskyrc new file mode 100644 index 0000000000..4d077c8292 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/.huskyrc @@ -0,0 +1,5 @@ +{ + "hooks": { + "pre-commit": "lint-staged" + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/.prettierrc b/packages/examples/fortune-v2/job-launcher/server/.prettierrc new file mode 100644 index 0000000000..e7ca2697ef --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/.prettierrc @@ -0,0 +1,7 @@ +{ + "arrowParens": "avoid", + "bracketSpacing": true, + "printWidth": 120, + "trailingComma": "all", + "singleQuote": false +} diff --git a/packages/examples/fortune-v2/job-launcher/server/LICENSE b/packages/examples/fortune-v2/job-launcher/server/LICENSE new file mode 100644 index 0000000000..c7b0077493 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2022 Human Protocol + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/examples/fortune-v2/job-launcher/server/README.md b/packages/examples/fortune-v2/job-launcher/server/README.md new file mode 100644 index 0000000000..b2f7cbfffe --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/README.md @@ -0,0 +1,66 @@ +# Job Launcher Server +Pre-reading: https://github.com/humanprotocol/.github/wiki + +## Overview +HUMAN is a multi-chain protocol with hundreds of thousands of decentralized workers operating across multiple chains. Anyone can assume the role of a worker and be paid for performing tasks. +Job requesters (people who want work performed) can launch jobs into the network and the jobs will be completed by workers. At a high level the HUMAN Protocol consists of two layers, the Routing Layer and the Execution Layer. The routing layer is responsible for routing jobs to the Layer 1 chains that offer the best execution terms (e.g tx cost, speed, liquidity). The execution layer is responsible for distributing individual tasks within a job to workers, verifying the results of those tasks, maintaining a reputation system for workers and remunerating workers for completed tasks. The two layers work together to facilitate the creation and completion of Jobs in the HUMAN Network. + +## Job Launcher +This repository contains the HUMAN Job Launcher Server, an open source and multi-chain application that can be used to launch jobs into the HUMAN network. Job Launchers may be operated by organizations, institutions and individuals who earn rewards and commission for the services they provide. There are many Job Launchers within the HUMAN network and each one can provide specialized services (i.e different job types). You can view all existing Job Launchers operating on the HUMAN network by checking out the Leaderboard page: ADD LINK This particular version of the job launcher is focused on data labeling services. A job launcher operator will provide this service to the community. Job requesters can then use this service to upload raw images, which will ultimately be annotated by real HUMANS. We expect this repository to be modified and extended to other use cases. + +## Tokenomics Model (Incentivization Mechanisms) +The open nature of the HUMAN Protocol means that any person or organization may operate core infrastructure and earn rewards for doing so. To prevent participants from acting maliciously, we have created a staking contract which requires all operators within the ecosystem to stake a security collateral. This is called Proof Of Balance. Any operator who is found to be breaching these rules will have their stake reduced by a predetermined amount, this is known as slashing. + +## Software Requirements +The Job Launcher Server requires of a number key components, before installing the Server you should ensure you have completed the pre-install steps below. + +1. Node.js and NPM +To see if you have installed Node.js and npm, execute the following commands in your terminal: + +`node -v` + +`npm -v` + +If you do not have these installed you can follow the guide here: +https://docs.npmjs.com/downloading-and-installing-node-js-and-npm + +2. Postgres Database +The server uses postgres as a database to store user emails and passwords. Ensure that you have installed postgres and created a database before installing the actual server itself. For postgres install instructions see here: +https://www.postgresql.org/download/ + +Make a note of the postgres username, password and database name. + +3. Hardhat +Hardhat is an Ethereum development environment. Compile your contracts and run them on a development network. To install Hardhat see here: +https://hardhat.org/hardhat-runner/docs/getting-started + +4. S3 credentials +The server uses S3 to store job details. To setup an S3 bucket and generate the API Key & Secret follow this guide: https://medium.com/@shamnad.p.s/how-to-create-an-s3-bucket-and-aws-access-key-id-and-secret-access-key-for-accessing-it-5653b6e54337 + +Take a note of the AWS region for the S3 bucket you just created, your API Key and Secret. + +## Installation +5. When installing for the first time it will be necessary to run a database migration. To do so you should execute the following command in your terminal: + + +6. Clone this repo to your local machine and change directory into the cloned repo: + +`git clone git@github.com:humanprotocol/human-protocol.git` + +7. Install using yarn + +`yarn install` + +8. Set the variable to development, testing or production. Populate the .env. file with the values you noted down in steps 2, 3 and 4. Use .env.example file to start. + +9. Run migrations using yarn + +`yarn migration:run` + +`yarn migration:create ` - Create new migration + +`yarn migration:revert` - Revert latest migration + +10. Run application using yarn +`yarn start` + diff --git a/packages/examples/fortune-v2/job-launcher/server/jest.config.json b/packages/examples/fortune-v2/job-launcher/server/jest.config.json new file mode 100644 index 0000000000..23ee05c934 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/jest.config.json @@ -0,0 +1,10 @@ +{ + "coverageDirectory": "../coverage", + "moduleFileExtensions": ["js", "json", "ts"], + "rootDir": "src", + "testEnvironment": "node", + "testRegex": ".spec.ts$", + "transform": { + ".+\\.(t|j)s$": "ts-jest" + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/ormconfig.json b/packages/examples/fortune-v2/job-launcher/server/ormconfig.json new file mode 100644 index 0000000000..119e333530 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/ormconfig.json @@ -0,0 +1,16 @@ +[ + { + "name": "default", + "type": "postgres", + "host": "localhost", + "port": 5432, + "username": "fortune", + "password": "fortune", + "database": "hmt-job-launcher", + "entities": ["dist/**/*.entity{ .ts,.js}"], + "synchronize": false, + "migrations": ["dist/migrations/*{.ts,.js}"], + "migrationsTableName": "migrations_typeorm", + "migrationsRun": true + } + ] \ No newline at end of file diff --git a/packages/examples/fortune-v2/job-launcher/server/package.json b/packages/examples/fortune-v2/job-launcher/server/package.json new file mode 100644 index 0000000000..b2e965f0f5 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/package.json @@ -0,0 +1,97 @@ +{ + "private": "true", + "name": "@human-protocol/job-launcher-server", + "version": "1.0.0", + "description": "Human Protocol | Job Launcher Server", + "license": "MIT", + "publishConfig": { + "registry": "https://npm.pkg.github.com/" + }, + "bugs": { + "url": "https://github.com/humanprotocol/human-protocol/issues" + }, + "title": "Human Protocol Foundation", + "engines": { + "node": "18.x" + }, + "main": "./dist/main.js", + "scripts": { + "build": "tsc", + "db:restart": "docker-compose down && docker-compose up -d", + "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"", + "kill": "sudo pkill -9 node", + "lint": "eslint . --fix", + "migration:create": "typeorm migration:create -d src/migrations -n", + "migration:generate": "typeorm migration:generate -d src/migrations -n", + "migration:revert": "typeorm migration:revert -- -d src/migrations", + "migration:run": "typeorm migration:run -- -d src/ormconfig.ts", + "migration:show": "typeorm migration:show -d src/migrations", + "prebuild": "rimraf dist/", + "prepublish": "npm run build", + "start": "NODE_ENV=${NODE_ENV:=development} tsc-watch --onSuccess \"node .\" --onFailure \"echo Compilation Failed\"", + "start:dev": "NODE_ENV=${NODE_ENV:=development} tsc", + "start:production": "NODE_ENV=${NODE_ENV:=production} tsc-watch --onSuccess \"node .\" --onFailure \"echo Compilation Failed\"", + "start:staging": "NODE_ENV=${NODE_ENV:=staging} node .", + "test": "NODE_ENV=${NODE_ENV:=test} jest --config jest.config.json --detectOpenHandles" + }, + "dependencies": { + "@nestjs/axios": "^2.0.0", + "@nestjs/common": "^9.3.9", + "@nestjs/config": "^2.3.1", + "@nestjs/core": "^9.3.9", + "@nestjs/jwt": "^10.0.2", + "@nestjs/passport": "^9.0.3", + "@nestjs/platform-express": "^9.3.9", + "@nestjs/schedule": "^2.2.0", + "@nestjs/swagger": "^6.2.1", + "@nestjs/terminus": "^9.2.1", + "@nestjs/testing": "^9.3.9", + "@nestjs/typeorm": "^9.0.1", + "@types/chai": "^4.3.4", + "axios": "^1.3.4", + "bcrypt": "^5.0.0", + "body-parser": "^1.20.2", + "class-transformer": "^0.5.1", + "class-validator": "^0.14.0", + "cookie-parser": "^1.4.6", + "express": "^4.18.2", + "express-session": "^1.17.3", + "helmet": "^6.0.1", + "nestjs-ethers": "^2.0.3", + "nestjs-minio-client": "^2.0.0", + "passport": "^0.6.0", + "passport-jwt": "^4.0.1", + "pg": "^8.10.0", + "reflect-metadata": "^0.1.13", + "rxjs": "^7.8.0", + "typeorm": "0.2.43", + "typeorm-naming-strategies": "^4.1.0", + "uuid": "^9.0.0", + "zxcvbn": "^4.4.2", + "bip39": "^3.1.0" + }, + "devDependencies": { + "@nestjs/testing": "^9.3.9", + "@types/chai": "^4.3.4", + "@types/express": "^4.17.17", + "@types/express-session": "^1.17.6", + "@types/passport": "^1.0.12", + "@types/passport-jwt": "^3.0.8", + "@types/passport-twitter": "^1.0.37", + "@types/uuid": "^9.0.1", + "@types/zxcvbn": "^4.4.1", + "@types/bcrypt": "^5.0.0", + "@types/cookie-parser": "^1.4.3", + "chai": "^4.3.7", + "eslint-config-standard": "^17.0.0", + "eslint-import-resolver-ts": "^0.4.2", + "eslint-plugin-node": "^11.1.0", + "eslint-plugin-promise": "^6.1.1", + "eslint-plugin-standard": "^5.0.0", + "ethereum-types": "^3.7.1", + "passport-facebook": "^3.0.0", + "passport-google-oauth": "^2.0.0", + "rimraf": "^4.3.1", + "tsc-watch": "^6.0.0" + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/app.controller.ts b/packages/examples/fortune-v2/job-launcher/server/src/app.controller.ts new file mode 100644 index 0000000000..ee80dce026 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/app.controller.ts @@ -0,0 +1,13 @@ +import { Controller, Get, Redirect } from "@nestjs/common"; + +import { Public } from "./common/decorators"; +import { ApiTags } from "@nestjs/swagger"; + +@Controller("/") +@ApiTags("Main") +export class AppController { + @Public() + @Get("/") + @Redirect("/swagger", 301) + public redirect(): void {} +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/app.module.ts b/packages/examples/fortune-v2/job-launcher/server/src/app.module.ts new file mode 100644 index 0000000000..0e44ef5b06 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/app.module.ts @@ -0,0 +1,40 @@ +import { Module } from "@nestjs/common"; +import { APP_GUARD, APP_PIPE } from "@nestjs/core"; +import { ConfigModule } from "@nestjs/config"; +import { ScheduleModule } from "@nestjs/schedule"; +import { AppController } from "./app.controller"; +import { DatabaseModule } from "./database/database.module"; +import { JwtHttpGuard, RolesGuard } from "./common/guards"; +import { HttpValidationPipe } from "./common/pipes"; +import { HealthModule } from "./modules/health/health.module"; +import { AuthModule } from "./modules/auth/auth.module"; +import { UserModule } from "./modules/user/user.module"; + +@Module({ + providers: [ + { + provide: APP_GUARD, + useClass: JwtHttpGuard, + }, + { + provide: APP_GUARD, + useClass: RolesGuard, + }, + { + provide: APP_PIPE, + useClass: HttpValidationPipe, + }, + ], + imports: [ + ScheduleModule.forRoot(), + ConfigModule.forRoot({ + envFilePath: `.env.${process.env.NODE_ENV as string}`, + }), + DatabaseModule, + HealthModule, + AuthModule, + UserModule, + ], + controllers: [AppController], +}) +export class AppModule {} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/collection/index.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/collection/index.ts new file mode 100644 index 0000000000..fdb0e940b7 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/collection/index.ts @@ -0,0 +1,3 @@ +export * from "./pagination"; +export * from "./search"; +export * from "./sort"; diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/collection/pagination.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/collection/pagination.ts new file mode 100644 index 0000000000..a2a7a33594 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/collection/pagination.ts @@ -0,0 +1,28 @@ +import { ApiPropertyOptional } from "@nestjs/swagger"; +import { IsNumber, IsOptional } from "class-validator"; +import { Type } from "class-transformer"; + +export interface IPaginationDto { + skip: number; + take: number; +} + +export class PaginationDto implements IPaginationDto { + @ApiPropertyOptional({ + type: Number, + default: 0, + }) + @IsNumber() + @IsOptional() + @Type(() => Number) + public skip = 0; + + @ApiPropertyOptional({ + type: Number, + default: 25, + }) + @IsNumber() + @IsOptional() + @Type(() => Number) + public take = 25; +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/collection/search.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/collection/search.ts new file mode 100644 index 0000000000..ca54f9004e --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/collection/search.ts @@ -0,0 +1,15 @@ +import { ApiPropertyOptional } from "@nestjs/swagger"; +import { IsString, IsOptional } from "class-validator"; + +import { IPaginationDto, PaginationDto } from "./pagination"; + +export interface ISearchDto extends IPaginationDto { + query: string; +} + +export class SearchDto extends PaginationDto implements ISearchDto { + @ApiPropertyOptional() + @IsOptional() + @IsString() + public query: string; +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/collection/sort.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/collection/sort.ts new file mode 100644 index 0000000000..f42cba3015 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/collection/sort.ts @@ -0,0 +1,27 @@ +import { ApiPropertyOptional } from "@nestjs/swagger"; +import { IsString, IsOptional, IsEnum } from "class-validator"; +import { ISearchDto, SearchDto } from "./search"; + +export enum SortDirection { + ASC = "ASC", + DESC = "DESC", +} + +export interface ISortDto extends ISearchDto { + sort: SortDirection; + sortBy: keyof T; +} + +export class SortDto extends SearchDto implements ISortDto { + @ApiPropertyOptional() + @IsOptional() + @IsString() + public sortBy: keyof T; + + @ApiPropertyOptional({ + enum: SortDirection, + }) + @IsOptional() + @IsEnum(SortDirection) + public sort: SortDirection; +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/constants/errors.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/constants/errors.ts new file mode 100644 index 0000000000..7f6ae28d8a --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/constants/errors.ts @@ -0,0 +1,50 @@ +/** + * Represents error messages related to auth. + */ +export enum ErrorAuth { + Unauthorized = "Unauthorized", +} + +/** + * Represents error messages associated with a job. + */ +export enum ErrorJob { + NotFound = "Job not found", + NotCreated = "Job has not been created", + NotEnoughFunds = "Not enough funds" +} + +/** + * Represents error messages related to escrow. + */ +export enum ErrorEscrow { + NotFound = "Escrow not found", + NotCreated = "Escrow has not been created" +} + +/** + * Represents error messages related to user. + */ +export enum ErrorUser { + NotFound = "User not found", + DuplicateUsername = "Duplicate username", + DuplicateEmail = "Duplicate email", +} + +/** + * Represents error messages related to payment. + */ +export enum ErrorPayment { + NotFound = "Payment not found", + NotSuccess = "Unseccssful payment", + CustomerNotFound = "Customer not found", + IncorrectAmount = "Incorrect amount" +} + +/** + * Represents error messages related to bucket. + */ +export enum ErrorBucket { + NotPublic = "Bucket is not public", + UnableSaveFile = "Unable to save file.", +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/constants/index.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/constants/index.ts new file mode 100644 index 0000000000..87be4deec2 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/constants/index.ts @@ -0,0 +1,4 @@ +export const NS = "hmt"; +export const COMPANY_NAME = "Human Protocol Foundation"; +export const COINGECKO_API_URL = "https://api.coingecko.com/api/v3/simple/price"; +export const JOB_RETRIES_COUNT_THRESHOLD = 3; \ No newline at end of file diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/base.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/base.ts new file mode 100644 index 0000000000..8ad596c4d9 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/base.ts @@ -0,0 +1,5 @@ +export interface IBase { + id: number; + createdAt: Date; + updatedAt: Date; +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/index.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/index.ts new file mode 100644 index 0000000000..084d56230f --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/index.ts @@ -0,0 +1,3 @@ +export * from "./user"; +export * from "./public"; +export * from "./role"; \ No newline at end of file diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/public.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/public.ts new file mode 100644 index 0000000000..bb932525f9 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/public.ts @@ -0,0 +1,3 @@ +import { SetMetadata } from "@nestjs/common"; + +export const Public = (): ((target: any, key?: any, descriptor?: any) => any) => SetMetadata("isPublic", true); diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/role.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/role.ts new file mode 100644 index 0000000000..0d249d0f1c --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/role.ts @@ -0,0 +1,4 @@ +import { SetMetadata } from "@nestjs/common"; + +export const Roles = (...roles: Array): ((target: any, key?: any, descriptor?: any) => any) => + SetMetadata("roles", [...roles]); diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/user.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/user.ts new file mode 100644 index 0000000000..5e5137b36f --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/decorators/user.ts @@ -0,0 +1,19 @@ +import { createParamDecorator, ExecutionContext } from "@nestjs/common"; +import { UserStatus, UserType } from "../enums/user"; +import { IBase } from "./base"; + +export interface IUser extends IBase { + password: string; + email: string; + status: UserStatus; + type: UserType; +} + +/** + * Custom decorator to retrieve the currently logged-in user. + * Returns the user object from the request context. + */ +export const User = createParamDecorator((_data: unknown, ctx: ExecutionContext) => { + const request = ctx.switchToHttp().getRequest(); + return (request.user as IUser) || null; +}); diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/dynamic/index.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/dynamic/index.ts new file mode 100644 index 0000000000..50975815c2 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/dynamic/index.ts @@ -0,0 +1,145 @@ +import { DynamicModule, Provider, Type } from "@nestjs/common"; +import { ModuleMetadata } from "@nestjs/common/interfaces"; +import { firstValueFrom, interval, race, Subject } from "rxjs"; +import { first, map } from "rxjs/operators"; + +type InjectionToken = string | symbol | Type; + +export interface IModuleConfigFactory { + createModuleConfig(): Promise | T; +} + + +export interface IAsyncModuleConfig extends Pick { + useExisting?: { + value: IModuleConfigFactory; + provide?: InjectionToken; + }; + useClass?: Type>; + useFactory?: (...args: any[]) => Promise | T; + inject?: any[]; +} + +/** + * Creates a module configuration provider based on the provided options. + * @param provide - The injection token for the module configuration. + * @param options - The options for creating the module configuration provider. + * @returns An array of providers for the module configuration. + */ +export function createModuleConfigProvider(provide: InjectionToken, options: IAsyncModuleConfig): Provider[] { + if (options.useFactory) { + return [ + { + provide, + useFactory: options.useFactory, + inject: options.inject || [], + }, + ]; + } + + const optionsProvider = { + provide, + useFactory: async (moduleConfigFactory: IModuleConfigFactory) => { + return moduleConfigFactory.createModuleConfig(); + }, + inject: [options.useClass || options.useExisting?.provide || (options.useExisting as any).value.constructor.name], + }; + + if (options.useClass) { + return [ + optionsProvider, + { + provide: options.useClass, + useClass: options.useClass, + }, + ]; + } + + if (options.useExisting) { + return [ + optionsProvider, + { + provide: options.useExisting.provide || options.useExisting.value.constructor.name, + useValue: options.useExisting.value, + }, + ]; + } + + return []; +} + +export interface IConfigurableDynamicRootModule { + new (): Type; + + moduleSubject: Subject; + + forRoot(moduleCtor: Type, moduleConfig: U): DynamicModule; + + forRootAsync(moduleCtor: Type, asyncModuleConfig: IAsyncModuleConfig): DynamicModule; + + externallyConfigured(moduleCtor: Type, wait: number): Promise; +} + +export function createConfigurableDynamicRootModule( + moduleConfigToken: InjectionToken, + moduleProperties: Partial> = { + imports: [], + exports: [], + providers: [], + }, +): IConfigurableDynamicRootModule { + abstract class DynamicRootModule { + static moduleSubject = new Subject(); + + static forRootAsync(moduleCtor: Type, asyncModuleConfig: IAsyncModuleConfig): DynamicModule { + const dynamicModule = { + module: moduleCtor, + imports: [...(asyncModuleConfig.imports || []), ...(moduleProperties.imports || [])], + exports: [...(asyncModuleConfig.exports || []), ...(moduleProperties.exports || [])], + providers: [ + ...createModuleConfigProvider(moduleConfigToken, asyncModuleConfig), + ...(moduleProperties.providers || []), + ], + }; + + DynamicRootModule.moduleSubject.next(dynamicModule); + + return dynamicModule; + } + + static forRoot(moduleCtor: Type, moduleConfig: U): DynamicModule { + const dynamicModule: DynamicModule = { + module: moduleCtor, + imports: [...(moduleProperties.imports || [])], + exports: [...(moduleProperties.exports || [])], + controllers: [...(moduleProperties.controllers || [])], + providers: [ + { + provide: moduleConfigToken, + useValue: moduleConfig, + }, + ...(moduleProperties.providers || []), + ], + }; + + DynamicRootModule.moduleSubject.next(dynamicModule); + + return dynamicModule; + } + + static async externallyConfigured(moduleCtor: Type, wait: number): Promise { + const timeout$ = interval(wait).pipe( + first(), + map(() => { + throw new Error( + `Expected ${moduleCtor.name} to be configured by at last one Module but it was not configured within ${wait}ms`, + ); + }), + ); + + return firstValueFrom(race(timeout$, DynamicRootModule.moduleSubject.pipe(first()))); + } + } + + return DynamicRootModule as IConfigurableDynamicRootModule; +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/enums/user.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/enums/user.ts new file mode 100644 index 0000000000..dfea5467b6 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/enums/user.ts @@ -0,0 +1,10 @@ +export enum UserStatus { + ACTIVE = "ACTIVE", + INACTIVE = "INACTIVE", + PENDING = "PENDING", +} + +export enum UserType { + OPERATOR = "OPERATOR", + REQUESTER = "REQUESTER", +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/guards/index.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/guards/index.ts new file mode 100644 index 0000000000..d7b87d128c --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/guards/index.ts @@ -0,0 +1,2 @@ +export * from "./jwt.http"; +export * from "./roles"; diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/guards/jwt.http.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/guards/jwt.http.ts new file mode 100644 index 0000000000..1ed4068d8b --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/guards/jwt.http.ts @@ -0,0 +1,28 @@ +import { CanActivate, ExecutionContext, Injectable, UnauthorizedException } from "@nestjs/common"; +import { Reflector } from "@nestjs/core"; +import { AuthGuard } from "@nestjs/passport"; + +@Injectable() +export class JwtHttpGuard extends AuthGuard("jwt-http") implements CanActivate { + constructor(private readonly reflector: Reflector) { + super(); + } + + public async canActivate(context: ExecutionContext): Promise { + // `super` has to be called to set `user` on `request` + // see https://github.com/nestjs/passport/blob/master/lib/auth.guard.ts + return (super.canActivate(context) as Promise).catch(e => { + const isPublic = this.reflector.getAllAndOverride("isPublic", [ + context.getHandler(), + context.getClass(), + ]); + + if (isPublic) { + return true; + } + + console.error(e); + throw new UnauthorizedException("Unauthorized"); + }); + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/guards/roles.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/guards/roles.ts new file mode 100644 index 0000000000..f89bbb276e --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/guards/roles.ts @@ -0,0 +1,24 @@ +import { CanActivate, ExecutionContext, Injectable } from "@nestjs/common"; +import { Reflector } from "@nestjs/core"; +import { UserType } from "../enums/user"; + +@Injectable() +export class RolesGuard implements CanActivate { + constructor(private readonly reflector: Reflector) {} + + canActivate(context: ExecutionContext): boolean { + const types = this.reflector.getAllAndOverride("roles", [context.getHandler(), context.getClass()]); + + if (!types || !types.length) { + return true; + } + + const request = context.switchToHttp().getRequest(); + + if (!request.user) { + return false; + } + + return types.includes(request.user.type); + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/interceptors/index.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/interceptors/index.ts new file mode 100644 index 0000000000..207263c3cf --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/interceptors/index.ts @@ -0,0 +1,2 @@ +export * from "./not-found"; +export * from "./pagination"; diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/interceptors/not-found.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/interceptors/not-found.ts new file mode 100644 index 0000000000..e1e6a57a0e --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/interceptors/not-found.ts @@ -0,0 +1,16 @@ +import { Observable } from "rxjs"; +import { tap } from "rxjs/operators"; +import { ExecutionContext, Injectable, NestInterceptor, NotFoundException, CallHandler } from "@nestjs/common"; + +@Injectable() +export class NotFoundInterceptor implements NestInterceptor { + intercept(_context: ExecutionContext, next: CallHandler): Observable { + return next.handle().pipe( + tap(data => { + if (data === void 0 || data === null) { + throw new NotFoundException(); + } + }), + ); + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/interceptors/pagination.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/interceptors/pagination.ts new file mode 100644 index 0000000000..63b869d773 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/interceptors/pagination.ts @@ -0,0 +1,10 @@ +import { Observable } from "rxjs"; +import { map } from "rxjs/operators"; +import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from "@nestjs/common"; + +@Injectable() +export class PaginationInterceptor implements NestInterceptor { + intercept(_context: ExecutionContext, next: CallHandler): Observable { + return next.handle().pipe(map(([rows, count]) => ({ rows, count }))); + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/pipes/index.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/pipes/index.ts new file mode 100644 index 0000000000..99455b8180 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/pipes/index.ts @@ -0,0 +1 @@ +export * from "./validation"; diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/pipes/validation.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/pipes/validation.ts new file mode 100644 index 0000000000..5c6a92d342 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/pipes/validation.ts @@ -0,0 +1,21 @@ +import { + BadRequestException, + Injectable, + ValidationError, + ValidationPipe, + ValidationPipeOptions, +} from "@nestjs/common"; + +@Injectable() +export class HttpValidationPipe extends ValidationPipe { + constructor(options?: ValidationPipeOptions) { + super({ + exceptionFactory: (errors: ValidationError[]): BadRequestException => new BadRequestException(errors), + transform: true, + whitelist: true, + forbidNonWhitelisted: true, + forbidUnknownValues: true, + ...options, + }); + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/validators/confirm.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/validators/confirm.ts new file mode 100644 index 0000000000..8dab8e84c6 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/validators/confirm.ts @@ -0,0 +1,63 @@ +import { + registerDecorator, + ValidationArguments, + ValidationOptions, + ValidatorConstraint, + ValidatorConstraintInterface, +} from "class-validator"; + +interface IConfirmConstraints { + required: boolean; + relatedPropertyName: string; +} + +@ValidatorConstraint() +class ValidateConfirm implements ValidatorConstraintInterface { + private reason: string; + + public validate(value: unknown, args: ValidationArguments): boolean { + this.reason = ValidateConfirm.isValid(value, args); + return !this.reason; + } + + public defaultMessage(): string { + return this.reason; + } + + private static isValid(value: unknown, args: ValidationArguments): string { + const { relatedPropertyName = "password" }: IConfirmConstraints = args.constraints[0]; + + const relatedValue = (args.object as any)[relatedPropertyName]; + + if (typeof value === "undefined" || value === "") { + if (relatedValue) { + return "valueMissing"; + } else { + return ""; + } + } + + if (typeof value !== "string") { + return "typeMismatch"; + } + + if (relatedValue !== value) { + return "badInput"; + } + + return ""; + } +} + +export function IsConfirm(constraints: Partial = {}, validationOptions?: ValidationOptions) { + return (object: Record, propertyName: string): void => { + registerDecorator({ + name: "isConfirm", + target: object.constructor, + propertyName, + constraints: [constraints], + options: validationOptions, + validator: ValidateConfirm, + }); + }; +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/validators/index.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/validators/index.ts new file mode 100644 index 0000000000..417cf0ba9a --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/validators/index.ts @@ -0,0 +1,2 @@ +export * from "./password"; +export * from "./confirm"; diff --git a/packages/examples/fortune-v2/job-launcher/server/src/common/validators/password.ts b/packages/examples/fortune-v2/job-launcher/server/src/common/validators/password.ts new file mode 100644 index 0000000000..f1d024bb6a --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/common/validators/password.ts @@ -0,0 +1,62 @@ +import { + registerDecorator, + ValidationArguments, + ValidationOptions, + ValidatorConstraint, + ValidatorConstraintInterface, +} from "class-validator"; +import zxcvbn from "zxcvbn"; + +interface IPasswordConstraints { + required: boolean; + score: number; +} + +@ValidatorConstraint() +class ValidatePassword implements ValidatorConstraintInterface { + private reason: string; + + public validate(value: unknown, args: ValidationArguments): boolean { + this.reason = ValidatePassword.isValid(value, args); + return !this.reason; + } + + public defaultMessage(): string { + return this.reason; + } + + private static isValid(value: unknown, args: ValidationArguments): string { + const { required = true, score = 0 }: IPasswordConstraints = args.constraints[0]; + + if (typeof value === "undefined" || value === "") { + if (required) { + return "valueMissing"; + } else { + return ""; + } + } + + if (typeof value !== "string") { + return "typeMismatch"; + } + + if (zxcvbn(value).score < score) { + return "weak"; + } + + return ""; + } +} + +export function IsPassword(constraints: Partial = {}, validationOptions?: ValidationOptions) { + return (object: Record, propertyName: string): void => { + registerDecorator({ + name: "isPassword", + target: object.constructor, + propertyName, + constraints: [constraints], + options: validationOptions, + validator: ValidatePassword, + }); + }; +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/database/base.entity.ts b/packages/examples/fortune-v2/job-launcher/server/src/database/base.entity.ts new file mode 100644 index 0000000000..d3c6e3e089 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/database/base.entity.ts @@ -0,0 +1,25 @@ +import { BaseEntity as OrmBaseEntity, BeforeInsert, BeforeUpdate, Column, PrimaryGeneratedColumn } from "typeorm"; + +export abstract class BaseEntity extends OrmBaseEntity { + @PrimaryGeneratedColumn() + public id: number; + + @Column({ type: "timestamptz" }) + public createdAt: Date; + + @Column({ type: "timestamptz" }) + public updatedAt: Date; + + @BeforeInsert() + public beforeInsert(): void { + const date = new Date(); + this.createdAt = date; + this.updatedAt = date; + } + + @BeforeUpdate() + public beforeUpdate(): void { + const date = new Date(); + this.updatedAt = date; + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/database/database.module.ts b/packages/examples/fortune-v2/job-launcher/server/src/database/database.module.ts new file mode 100644 index 0000000000..8a16aff574 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/database/database.module.ts @@ -0,0 +1,50 @@ +import { Module } from "@nestjs/common"; +import { ConfigModule, ConfigService } from "@nestjs/config"; +import { TypeOrmModule } from "@nestjs/typeorm"; +import path from "path"; +import { SnakeNamingStrategy } from "typeorm-naming-strategies"; +import { AuthEntity } from "../modules/auth/auth.entity"; +import { NS } from "../common/constants"; +import { TokenEntity } from "../modules/auth/token.entity"; +import { UserEntity } from "../modules/user/user.entity"; + +import { TypeOrmLoggerModule, TypeOrmLoggerService } from "./typeorm"; + +@Module({ + imports: [ + TypeOrmModule.forRootAsync({ + imports: [TypeOrmLoggerModule, ConfigModule], + inject: [TypeOrmLoggerService, ConfigService], + useFactory: (typeOrmLoggerService: TypeOrmLoggerService, configService: ConfigService) => { + typeOrmLoggerService.setOptions("all"); + return { + name: "default", + type: "postgres", + entities: [AuthEntity, TokenEntity, UserEntity], + // We are using migrations, synchronize should be set to false. + synchronize: false, + // Run migrations automatically, + // you can disable this if you prefer running migration manually. + migrationsTableName: NS, + migrationsTransactionMode: "each", + namingStrategy: new SnakeNamingStrategy(), + logging: process.env.NODE_ENV === "development" || process.env.NODE_ENV === "staging", + // Allow both start:prod and start:dev to use migrations + // __dirname is either dist or server folder, meaning either + // the compiled js in prod or the ts in dev. + migrations: [path.join(__dirname, "/migrations/**/*{.ts,.js}")], + //"migrations": ["dist/migrations/*{.ts,.js}"], + logger: typeOrmLoggerService, + host: configService.get("POSTGRES_HOST", "localhost"), + port: configService.get("POSTGRES_PORT", 5432), + username: configService.get("POSTGRES_USER", "fortune"), + password: configService.get("POSTGRES_PASSWORD", "fortune"), + database: configService.get("POSTGRES_DB", "hmt-job-launcher"), + keepConnectionAlive: configService.get("NODE_ENV") === "test", + migrationsRun: false, + }; + }, + }), + ], +}) +export class DatabaseModule {} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677845576145-addShema.ts b/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677845576145-addShema.ts new file mode 100644 index 0000000000..b47d953f4d --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677845576145-addShema.ts @@ -0,0 +1,14 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; +import { NS } from "../../common/constants"; + +export class addShema1677845576145 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.createSchema(NS, true); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropSchema(NS); + } + +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677845804077-installExtension.ts b/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677845804077-installExtension.ts new file mode 100644 index 0000000000..532dc86f31 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677845804077-installExtension.ts @@ -0,0 +1,13 @@ +import {MigrationInterface, QueryRunner} from "typeorm"; + +export class installExtension1677845804077 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(`CREATE EXTENSION IF NOT EXISTS "uuid-ossp";`); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query(`-- do nothing`); + } + +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677867973538-addUserTable.ts b/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677867973538-addUserTable.ts new file mode 100644 index 0000000000..b0469be2d3 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677867973538-addUserTable.ts @@ -0,0 +1,68 @@ +import {MigrationInterface, QueryRunner, Table} from "typeorm"; +import { NS } from "../../common/constants"; + +export class addUserTable1677867973538 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + CREATE TYPE ${NS}.user_type_enum AS ENUM ( + 'OPERATOR', + 'REQUESTER' + ); + `); + + await queryRunner.query(` + CREATE TYPE ${NS}.user_status_enum AS ENUM ( + 'ACTIVE', + 'INACTIVE', + 'PENDING' + ); + `); + + const table = new Table({ + name: `${NS}.user`, + columns: [ + { + name: "id", + type: "serial", + isPrimary: true, + }, + { + name: "password", + type: "varchar", + }, + { + name: "email", + type: "varchar", + isUnique: true, + isNullable: true, + }, + { + name: "type", + type: `${NS}.user_type_enum`, + }, + { + name: "status", + type: `${NS}.user_status_enum`, + }, + { + name: "created_at", + type: "timestamptz", + }, + { + name: "updated_at", + type: "timestamptz", + }, + ], + }); + + await queryRunner.createTable(table, true); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable(`${NS}.user`); + await queryRunner.query(`DROP TYPE ${NS}.user_type_enum;`); + await queryRunner.query(`DROP TYPE ${NS}.user_status_enum;`); + } + +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677867985970-addAuthTable.ts b/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677867985970-addAuthTable.ts new file mode 100644 index 0000000000..e806ee6bf2 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677867985970-addAuthTable.ts @@ -0,0 +1,77 @@ +import {MigrationInterface, QueryRunner, Table} from "typeorm"; +import { NS } from "../../common/constants"; + +export class addAuthTable1677867985970 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + const table = new Table({ + name: `${NS}.auth`, + columns: [ + { + name: "id", + type: "serial", + isPrimary: true, + }, + { + name: "refresh_token", + type: "varchar", + }, + { + name: "refresh_token_expires_at", + type: "bigint", + }, + { + name: "user_id", + type: "int", + }, + { + name: "ip", + type: "varchar", + default: "'0.0.0.0'", + }, + { + name: "created_at", + type: "timestamptz", + }, + { + name: "updated_at", + type: "timestamptz", + }, + ], + foreignKeys: [ + { + columnNames: ["user_id"], + referencedColumnNames: ["id"], + referencedTableName: `${NS}.user`, + onDelete: "CASCADE", + }, + ], + }); + + await queryRunner.createTable(table, true); + + await queryRunner.query(` + CREATE OR REPLACE FUNCTION delete_expired_auth() RETURNS trigger + LANGUAGE plpgsql + AS $$ + BEGIN + DELETE FROM ${NS}.auth WHERE created_at < NOW() - INTERVAL '30 days'; + RETURN NEW; + END; + $$; + `); + + await queryRunner.query(` + DROP TRIGGER IF EXISTS delete_expired_auth_trigger ON ${NS}.auth; + CREATE TRIGGER delete_expired_auth_trigger + AFTER INSERT ON ${NS}.auth + EXECUTE PROCEDURE delete_expired_auth() + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable(`${NS}.auth`); + await queryRunner.query("DROP FUNCTION delete_expired_auth();"); + } + +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677867996573-addTokenTable.ts b/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677867996573-addTokenTable.ts new file mode 100644 index 0000000000..5074f78604 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/database/migrations/1677867996573-addTokenTable.ts @@ -0,0 +1,82 @@ +import {MigrationInterface, QueryRunner, Table} from "typeorm"; +import { NS } from "../../common/constants"; + +export class addTokenTable1677867996573 implements MigrationInterface { + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query(` + CREATE TYPE ${NS}.token_type_enum AS ENUM ( + 'EMAIL', + 'PASSWORD' + ); + `); + + const table = new Table({ + name: `${NS}.token`, + columns: [ + { + name: "id", + type: "serial", + isPrimary: true, + }, + { + name: "uuid", + type: "uuid", + isUnique: true, + isGenerated: true, + generationStrategy: "uuid", + }, + { + name: "token_type", + type: `${NS}.token_type_enum`, + }, + { + name: "user_id", + type: "int", + }, + { + name: "created_at", + type: "timestamptz", + }, + { + name: "updated_at", + type: "timestamptz", + }, + ], + foreignKeys: [ + { + columnNames: ["user_id"], + referencedColumnNames: ["id"], + referencedTableName: `${NS}.user`, + onDelete: "CASCADE", + }, + ], + }); + + await queryRunner.createTable(table, true); + + await queryRunner.query(` + CREATE OR REPLACE FUNCTION delete_expired_tokens() RETURNS trigger + LANGUAGE plpgsql + AS $$ + BEGIN + DELETE FROM ${NS}.token WHERE created_at < NOW() - INTERVAL '1 hour'; + RETURN NEW; + END; + $$; + `); + + await queryRunner.query(` + CREATE TRIGGER delete_expired_tokens_trigger + AFTER INSERT ON ${NS}.token + EXECUTE PROCEDURE delete_expired_tokens() + `); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable(`${NS}.token`); + await queryRunner.query(`DROP TYPE ${NS}.token_type_enum;`); + await queryRunner.query("DROP FUNCTION delete_expired_tokens();"); + } + +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/database/typeorm/index.ts b/packages/examples/fortune-v2/job-launcher/server/src/database/typeorm/index.ts new file mode 100644 index 0000000000..720855bb48 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/database/typeorm/index.ts @@ -0,0 +1,2 @@ +export * from "./typeorm-logger.service"; +export * from "./typeorm-logger.module"; diff --git a/packages/examples/fortune-v2/job-launcher/server/src/database/typeorm/typeorm-logger.module.ts b/packages/examples/fortune-v2/job-launcher/server/src/database/typeorm/typeorm-logger.module.ts new file mode 100644 index 0000000000..80c39a6459 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/database/typeorm/typeorm-logger.module.ts @@ -0,0 +1,9 @@ +import { Module, Logger } from "@nestjs/common"; + +import { TypeOrmLoggerService } from "./typeorm-logger.service"; + +@Module({ + providers: [Logger, TypeOrmLoggerService], + exports: [TypeOrmLoggerService], +}) +export class TypeOrmLoggerModule {} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/database/typeorm/typeorm-logger.service.ts b/packages/examples/fortune-v2/job-launcher/server/src/database/typeorm/typeorm-logger.service.ts new file mode 100644 index 0000000000..5d0de2d109 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/database/typeorm/typeorm-logger.service.ts @@ -0,0 +1,71 @@ +import util from "util"; +import { Logger as TypeOrmLogger, LoggerOptions as TypeOrmLoggerOptions } from "typeorm"; +import { Inject, Injectable, Logger, LoggerService } from "@nestjs/common"; + +@Injectable() +export class TypeOrmLoggerService implements TypeOrmLogger { + private options: TypeOrmLoggerOptions = "all"; + + constructor(@Inject(Logger) private readonly loggerService: LoggerService) {} + + public setOptions(options: TypeOrmLoggerOptions = "all"): void { + this.options = options; + } + + logQuery(query: string, parameters?: any[]): void { + if ( + this.options === "all" || + this.options === true || + (this.options instanceof Array && this.options.indexOf("query") !== -1) + ) { + this.loggerService.log(`query : ${query} ${this.stringifyParams(parameters)}`, "TypeOrm"); + } + } + + logQueryError(error: string, query: string, parameters?: any[]): void { + if ( + this.options === "all" || + this.options === true || + (this.options instanceof Array && this.options.indexOf("error") !== -1) + ) { + this.loggerService.log(`query failed: ${query} ${this.stringifyParams(parameters)}`, "TypeOrm"); + this.loggerService.log(`error: ${error}`, "TypeOrm"); + } + } + + logQuerySlow(time: number, query: string, parameters?: any[]): void { + this.loggerService.log(`query is slow: ${query} ${this.stringifyParams(parameters)}`, "TypeOrm"); + this.loggerService.log(`execution time: ${time}`, "TypeOrm"); + } + + logSchemaBuild(message: string): void { + if (this.options === "all" || (this.options instanceof Array && this.options.indexOf("schema") !== -1)) { + this.loggerService.log(message, "TypeOrm"); + } + } + + logMigration(message: string): void { + this.loggerService.log(message, "TypeOrm"); + } + + log(level: "log" | "info" | "warn", message: unknown): void { + switch (level) { + case "log": + if (this.options === "all" || (this.options instanceof Array && this.options.indexOf("log") !== -1)) + this.loggerService.log(message, "TypeOrm"); + break; + case "info": + if (this.options === "all" || (this.options instanceof Array && this.options.indexOf("info") !== -1)) + this.loggerService.log(message, "TypeOrm"); + break; + case "warn": + if (this.options === "all" || (this.options instanceof Array && this.options.indexOf("warn") !== -1)) + this.loggerService.warn(message, "TypeOrm"); + break; + } + } + + protected stringifyParams(parameters: any[] = []): string { + return parameters.length ? ` -- PARAMETERS: ${util.inspect(parameters)}` : ""; + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/main.ts b/packages/examples/fortune-v2/job-launcher/server/src/main.ts new file mode 100644 index 0000000000..4933ddeb5d --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/main.ts @@ -0,0 +1,66 @@ +import session from "express-session"; +import { NestFactory } from "@nestjs/core"; +import { ConfigService } from "@nestjs/config"; +import { NestExpressApplication } from "@nestjs/platform-express"; +import { DocumentBuilder, SwaggerModule } from "@nestjs/swagger"; +import { json, urlencoded } from "body-parser"; +import { useContainer } from "class-validator"; +import helmet from "helmet"; +import cookieParser from 'cookie-parser'; + +import { AppModule } from "./app.module"; + +async function bootstrap() { + const app = await NestFactory.create(AppModule, { cors: true }); + + const configService: ConfigService = app.get(ConfigService); + + const baseUrl = configService.get("FE_URL", "http://localhost:3001"); + + app.enableCors({ + origin: + process.env.NODE_ENV === "development" || process.env.NODE_ENV === "staging" + ? [`http://localhost:3001`, `http://127.0.0.1:3001`, `http://0.0.0.0:3001`, baseUrl] + : [baseUrl], + credentials: true, + exposedHeaders: ["Content-Disposition"], + }); + + useContainer(app.select(AppModule), { fallbackOnErrors: true }); + + app.use(cookieParser()); + + const sessionSecret = configService.get("SESSION_SECRET", ""); + + app.use( + session({ + secret: sessionSecret, + resave: false, + saveUninitialized: false, + + }), + ); + app.use(json({ limit: "5mb" })); + app.use(urlencoded({ limit: "5mb", extended: true })); + + const config = new DocumentBuilder() + .addBearerAuth() + .setTitle("Fortune Exchange Oracle API") + .setDescription("Swagger Fortune Exchange Oracle API") + .setVersion("1.0") + .build(); + const document = SwaggerModule.createDocument(app, config); + SwaggerModule.setup("swagger", app, document); + + const host = configService.get("HOST", "localhost"); + const port = configService.get("PORT", "5000"); + + app.use(helmet()); + + await app.listen(port, host, async () => { + console.info(`API server is running on http://${host}:${port}`); + }); +} + +void bootstrap(); + diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.dto.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.dto.ts new file mode 100644 index 0000000000..06a54b51ed --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.dto.ts @@ -0,0 +1,81 @@ +import { ApiProperty } from "@nestjs/swagger"; +import { IsEmail, Matches, IsString } from "class-validator"; +import { Transform } from "class-transformer"; +import { IsConfirm, IsPassword } from "../../common/validators"; +import { UserEntity } from "../user/user.entity"; +import { TokenType } from "../auth/token.entity"; + +export class ForgotPasswordDto { + @ApiProperty() + @IsEmail() + @Transform(({ value }: { value: string }) => value.toLowerCase()) + public email: string; +} + +export class SignInDto { + @ApiProperty() + @IsEmail() + @Transform(({ value }: { value: string }) => value.toLowerCase()) + public email: string; + + @ApiProperty() + @IsString() + public password: string; +} + +export class LogoutDto { + @ApiProperty() + @IsString() + public refreshToken: string; +} + +export class ValidatePasswordDto { + @Matches (/^(?=.*[a-z])(?=.*[A-Z])(?=.*[0-9])(?=.*[!@#$%^&*])(?=.{8,})/, { + message: + 'Password is not strong enough. Password must be at least eight characters long and contain 1 upper, 1 lowercase, 1 number and 1 special character.', + }) + @ApiProperty() + @IsPassword() + public password: string; + + @ApiProperty() + @IsConfirm() + public confirm: string; +} + +export class RefreshDto { + @ApiProperty() + @IsString() + public refreshToken: string; +} + +export class ResendEmailVerificationDto { + @ApiProperty() + @IsEmail() + @Transform(({ value }: { value: string }) => value.toLowerCase()) + public email: string; +} + +export class RestorePasswordDto extends ValidatePasswordDto { + @ApiProperty() + @IsString() + public token: string; +} + +export class VerifyEmailDto { + @ApiProperty() + @IsString() + public token: string; +} + +export class TokenCreateDto { + public tokenType: TokenType; + public user: UserEntity; +} + +export interface IJwt { + accessToken: string; + accessTokenExpiresAt: number; + refreshToken: string; + refreshTokenExpiresAt: number; +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.entity.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.entity.ts new file mode 100644 index 0000000000..d85fb7ddcd --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.entity.ts @@ -0,0 +1,30 @@ +import { Column, Entity, JoinColumn, OneToOne, PrimaryGeneratedColumn } from "typeorm"; + +import { NS } from "../../common/constants"; +import { UserEntity } from "../user/user.entity"; +import { BaseEntity } from "../../database/base.entity"; + +@Entity({ schema: NS, name: "auth" }) +export class AuthEntity extends BaseEntity { + @PrimaryGeneratedColumn() + public id: number; + + @Column({ type: "varchar" }) + public refreshToken: string; + + @Column({ type: "bigint" }) + public refreshTokenExpiresAt: number; + + @JoinColumn() + @OneToOne(_type => UserEntity) + public user: UserEntity; + + @Column({ type: "int" }) + public userId: number; + + @Column({ + type: "varchar", + select: false, + }) + public ip: string; +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.jwt.controller.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.jwt.controller.ts new file mode 100644 index 0000000000..d470135b22 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.jwt.controller.ts @@ -0,0 +1,72 @@ +import { Body, ClassSerializerInterceptor, Controller, HttpCode, Ip, Post, UseInterceptors } from "@nestjs/common"; + +import { AuthService } from "./auth.service"; +import { + ForgotPasswordDto, + SignInDto, + LogoutDto, + RefreshDto, + ResendEmailVerificationDto, + RestorePasswordDto, + VerifyEmailDto, + IJwt, +} from "./auth.dto"; +import { Public } from "../../common/decorators"; +import { ApiTags } from "@nestjs/swagger"; +import { UserCreateDto } from "../user/user.dto"; + +@Public() +@ApiTags("Auth") +@Controller("/auth") +export class AuthJwtController { + constructor(private readonly authService: AuthService) {} + + @Post("/signup") + @UseInterceptors(ClassSerializerInterceptor) + public async signup(@Body() data: UserCreateDto, @Ip() ip: string): Promise { + const userEntity = await this.authService.signup(data); + return this.authService.auth(userEntity, ip); + } + + @Post("/signin") + @HttpCode(200) + public signin(@Body() data: SignInDto, @Ip() ip: string): Promise { + return this.authService.signin(data, ip); + } + + @Post("/logout") + @HttpCode(204) + public async logout(@Body() data: LogoutDto): Promise { + await this.authService.logout(data); + } + + @Post("/refresh") + @HttpCode(200) + async refreshToken(@Body() data: RefreshDto, @Ip() ip: string): Promise { + return this.authService.refresh(data, ip); + } + + @Post("/forgot-password") + @HttpCode(204) + public forgotPassword(@Body() data: ForgotPasswordDto): Promise { + return this.authService.forgotPassword(data); + } + + @Post("/restore-password") + @HttpCode(204) + public restorePassword(@Body() data: RestorePasswordDto): Promise { + return this.authService.restorePassword(data); + } + + @Post("/email-verification") + @HttpCode(200) + public emailVerification(@Body() data: VerifyEmailDto, @Ip() ip: string): Promise { + return this.authService.emailVerification(data, ip); + } + + @Post("/resend-email-verification") + @HttpCode(204) + public resendEmailVerification(@Body() data: ResendEmailVerificationDto): Promise { + return this.authService.resendEmailVerification(data); + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.module.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.module.ts new file mode 100644 index 0000000000..d3a4dd0df9 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.module.ts @@ -0,0 +1,31 @@ +import { Module } from "@nestjs/common"; +import { JwtModule } from "@nestjs/jwt"; +import { ConfigService, ConfigModule } from "@nestjs/config"; +import { TypeOrmModule } from "@nestjs/typeorm"; + +import { UserModule } from "../user/user.module"; +import { JwtHttpStrategy } from "./strategy"; +import { AuthService } from "./auth.service"; +import { AuthJwtController } from "./auth.jwt.controller"; +import { AuthEntity } from "./auth.entity"; +import { TokenEntity } from "./token.entity"; +import { TokenRepository } from "./token.repository"; + +@Module({ + imports: [ + UserModule, + ConfigModule, + JwtModule.registerAsync({ + inject: [ConfigService], + imports: [ConfigModule], + useFactory: (configService: ConfigService) => ({ + secret: configService.get("JWT_SECRET", "secretkey"), + }), + }), + TypeOrmModule.forFeature([AuthEntity, TokenEntity]), + ], + providers: [JwtHttpStrategy, AuthService, TokenRepository], + controllers: [AuthJwtController], + exports: [AuthService], +}) +export class AuthModule {} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.service.spec.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.service.spec.ts new file mode 100644 index 0000000000..7183aab13d --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.service.spec.ts @@ -0,0 +1,44 @@ +import { Test, TestingModule } from "@nestjs/testing"; +import { TypeOrmModule } from "@nestjs/typeorm"; +import { PassportModule } from "@nestjs/passport"; +import { JwtModule } from "@nestjs/jwt"; +import { ConfigModule, ConfigService } from "@nestjs/config"; +import { DatabaseModule } from "../../database/database.module"; +import { UserModule } from "../user/user.module"; +import { AuthService } from "./auth.service"; +import { AuthEntity } from "./auth.entity"; +import { JwtHttpStrategy } from "./strategy"; +import { TokenEntity } from "./token.entity"; + +describe("AuthService", () => { + let authService: AuthService; + + beforeEach(async () => { + const module: TestingModule = await Test.createTestingModule({ + imports: [ + ConfigModule.forRoot({ + envFilePath: `.env.${process.env.NODE_ENV as string}`, + }), + DatabaseModule, + TypeOrmModule.forFeature([AuthEntity, TokenEntity]), + UserModule, + PassportModule, + ConfigModule, + JwtModule.registerAsync({ + imports: [ConfigModule], + inject: [ConfigService], + useFactory: (configService: ConfigService) => ({ + secret: configService.get("JWT_SECRET_KEY", "keyboard_cat"), + }), + }), + ], + providers: [AuthService, JwtHttpStrategy], + }).compile(); + + authService = module.get(AuthService); + }); + + it("should be defined", () => { + expect(authService).toBeDefined(); + }); +}); diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.service.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.service.ts new file mode 100644 index 0000000000..f68bed1e15 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/auth.service.ts @@ -0,0 +1,145 @@ +import { Injectable, Logger, NotFoundException, UnauthorizedException } from "@nestjs/common"; +import { JwtService } from "@nestjs/jwt"; +import { ConfigService } from "@nestjs/config"; +import { InjectRepository } from "@nestjs/typeorm"; +import { DeleteResult, FindConditions, Repository } from "typeorm"; +import { v4 } from "uuid"; + +import { UserEntity } from "../user/user.entity"; +import { UserService } from "../user/user.service"; +import { AuthEntity } from "./auth.entity"; +import { TokenType } from "./token.entity"; +import { UserStatus } from "../../common/enums/user"; +import { UserCreateDto } from "../user/user.dto"; +import { ForgotPasswordDto, IJwt, ResendEmailVerificationDto, RestorePasswordDto, SignInDto, VerifyEmailDto } from "./auth.dto"; +import { TokenRepository } from "./token.repository"; + +@Injectable() +export class AuthService { + private readonly logger = new Logger(AuthService.name); + + constructor( + private readonly jwtService: JwtService, + private readonly userService: UserService, + private readonly configService: ConfigService, + private readonly tokenRepository: TokenRepository, + @InjectRepository(AuthEntity) + private readonly authEntityRepository: Repository, + ) {} + + public async signin(data: SignInDto, ip: string): Promise { + const userEntity = await this.userService.getByCredentials(data.email, data.password); + + return this.auth(userEntity, ip); + } + + public async signup(data: UserCreateDto): Promise { + const userEntity = await this.userService.create(data); + + const tokenEntity = await this.tokenRepository.create({ tokenType: TokenType.EMAIL, user: userEntity }); + + this.logger.debug("Verification token: ", tokenEntity.uuid); + + // TODO: Add mail provider + + return userEntity; + } + + public async logout(where: FindConditions): Promise { + return this.authEntityRepository.delete(where); + } + + public async refresh(where: FindConditions, ip: string): Promise { + const authEntity = await this.authEntityRepository.findOne({ where, relations: ["user"] }); + + if (!authEntity || authEntity.refreshTokenExpiresAt < new Date().getTime()) { + throw new UnauthorizedException("Refresh token has expired"); + } + + if (authEntity.user.status !== UserStatus.ACTIVE) { + throw new UnauthorizedException("User not active"); + } + + return this.auth(authEntity.user, ip); + } + + public async auth(userEntity: UserEntity, ip: string): Promise { + const refreshToken = v4(); + const date = new Date(); + + const accessTokenExpiresIn = ~~this.configService.get("JWT_ACCESS_TOKEN_EXPIRES_IN", 5 * 60); + const refreshTokenExpiresIn = ~~this.configService.get("JWT_REFRESH_TOKEN_EXPIRES_IN", 30 * 24 * 60 * 60); + + await this.authEntityRepository + .create({ + user: userEntity, + refreshToken, + refreshTokenExpiresAt: date.getTime() + refreshTokenExpiresIn * 1000, + ip, + }) + .save(); + + return { + accessToken: this.jwtService.sign({ email: userEntity.email }, { expiresIn: accessTokenExpiresIn }), + refreshToken: refreshToken, + accessTokenExpiresAt: date.getTime() + accessTokenExpiresIn * 1000, + refreshTokenExpiresAt: date.getTime() + refreshTokenExpiresIn * 1000, + }; + } + + public async forgotPassword(data: ForgotPasswordDto): Promise { + const userEntity = await this.userService.getByEmail(data.email); + + if (!userEntity) return; + + if (userEntity.status !== UserStatus.ACTIVE) throw new UnauthorizedException("User is not active"); + + const tokenEntity = await this.tokenRepository.create({ tokenType: TokenType.PASSWORD, user: userEntity }); + + // Add mail provider + + this.logger.debug("Verification token: ", tokenEntity.uuid); + } + + public async restorePassword(data: RestorePasswordDto): Promise { + const tokenEntity = await this.tokenRepository.findOne({ uuid: data.token, tokenType: TokenType.PASSWORD }); + + if (!tokenEntity) { + throw new NotFoundException("Token not found"); + } + + await this.userService.updatePassword(tokenEntity.user, data); + + // Add mail provider + + this.logger.debug("Verification token: ", tokenEntity.uuid); + + await tokenEntity.remove(); + } + + public async emailVerification(data: VerifyEmailDto, ip: string): Promise { + const tokenEntity = await this.tokenRepository.findOne({ uuid: data.token, tokenType: TokenType.EMAIL }); + + if (!tokenEntity) { + throw new NotFoundException("Token not found"); + } + + await this.userService.activate(tokenEntity.user); + + await tokenEntity.remove(); + + return this.auth(tokenEntity.user, ip); + } + + public async resendEmailVerification(data: ResendEmailVerificationDto): Promise { + const userEntity = await this.userService.getByEmail(data.email); + + if (!userEntity) return; + + const tokenEntity = await this.tokenRepository.create({ tokenType: TokenType.EMAIL, user: userEntity }); + + // Add mail provider + + this.logger.debug("Verification token: ", tokenEntity.uuid); + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/strategy/index.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/strategy/index.ts new file mode 100644 index 0000000000..debf4aac1d --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/strategy/index.ts @@ -0,0 +1 @@ +export * from "./jwt.http"; diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/strategy/jwt.http.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/strategy/jwt.http.ts new file mode 100644 index 0000000000..0342fde084 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/strategy/jwt.http.ts @@ -0,0 +1,34 @@ +import { ExtractJwt, Strategy } from "passport-jwt"; +import { PassportStrategy } from "@nestjs/passport"; +import { Injectable, NotFoundException, UnauthorizedException } from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; + +import { UserEntity } from "../../user/user.entity"; +import { UserService } from "../../user/user.service"; +import { UserStatus } from "../../../common/enums/user"; + +@Injectable() +export class JwtHttpStrategy extends PassportStrategy(Strategy, "jwt-http") { + constructor(private readonly userService: UserService, private readonly configService: ConfigService) { + super({ + jwtFromRequest: ExtractJwt.fromAuthHeaderAsBearerToken(), + ignoreExpiration: false, + secretOrKey: configService.get("JWT_SECRET", "secretkey"), + }); + } + + public async validate(payload: { email: string }): Promise { + const email = payload.email.toLowerCase(); + const userEntity = await this.userService.getByEmail(email); + + if (!userEntity) { + throw new NotFoundException("User not found"); + } + + if (userEntity.status !== UserStatus.ACTIVE) { + throw new UnauthorizedException("User not active"); + } + + return userEntity; + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/token.entity.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/token.entity.ts new file mode 100644 index 0000000000..e980e0de92 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/token.entity.ts @@ -0,0 +1,36 @@ +import { Column, Entity, Generated, JoinColumn, OneToOne } from "typeorm"; + +import { UserEntity } from "../user/user.entity"; +import { BaseEntity } from "../../database/base.entity"; +import { NS } from "../../common/constants"; +import { IBase } from "../../common/decorators/base"; + +export enum TokenType { + EMAIL = "EMAIL", + PASSWORD = "PASSWORD", +} + +export interface IToken extends IBase { + uuid: string; + tokenType: TokenType; +} + +@Entity({ schema: NS, name: "token" }) +export class TokenEntity extends BaseEntity implements IToken { + @Column({ type: "uuid", unique: true }) + @Generated("uuid") + public uuid: string; + + @Column({ + type: "enum", + enum: TokenType, + }) + public tokenType: TokenType; + + @JoinColumn() + @OneToOne(_type => UserEntity) + public user: UserEntity; + + @Column({ type: "int" }) + public userId: number; +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/token.repository.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/token.repository.ts new file mode 100644 index 0000000000..3c0e06db61 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/auth/token.repository.ts @@ -0,0 +1,23 @@ +import { Injectable, Logger } from "@nestjs/common"; +import { InjectRepository } from "@nestjs/typeorm"; +import { FindConditions, Repository } from "typeorm"; +import { TokenEntity } from "./token.entity"; +import { TokenCreateDto } from "./auth.dto"; + +@Injectable() +export class TokenRepository { + constructor( + @InjectRepository(TokenEntity) + private readonly tokenEntityRepository: Repository, + ) {} + + public findOne(where: FindConditions): Promise { + return this.tokenEntityRepository.findOne({ where, relations: ["user"] }); + } + + public async create(dto: TokenCreateDto): Promise { + return this.tokenEntityRepository + .create(dto) + .save(); + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/health/health.controller.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/health/health.controller.ts new file mode 100644 index 0000000000..17514e3a36 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/health/health.controller.ts @@ -0,0 +1,28 @@ +import { Controller, Get } from "@nestjs/common"; +import { + HealthCheck, + HealthCheckResult, + HealthCheckService, + HealthIndicatorResult, + TypeOrmHealthIndicator, +} from "@nestjs/terminus"; +import { Public } from "../../common/decorators"; +import { ApiTags } from "@nestjs/swagger"; + +@Public() +@ApiTags("Health") +@Controller("/health") +export class HealthController { + constructor(private readonly health: HealthCheckService, private readonly db: TypeOrmHealthIndicator) {} + + @Get() + @HealthCheck() + readiness(): Promise { + return this.health.check([ + async (): Promise => + this.db.pingCheck("database", { + timeout: 5000, + }), + ]); + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/health/health.module.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/health/health.module.ts new file mode 100644 index 0000000000..e57794812d --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/health/health.module.ts @@ -0,0 +1,11 @@ +import { Module } from "@nestjs/common"; +import { TerminusModule } from "@nestjs/terminus"; +import { ConfigModule } from "@nestjs/config"; + +import { HealthController } from "./health.controller"; + +@Module({ + imports: [TerminusModule, ConfigModule], + controllers: [HealthController], +}) +export class HealthModule {} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.controller.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.controller.ts new file mode 100644 index 0000000000..d2e7362ec7 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.controller.ts @@ -0,0 +1,19 @@ +import { Body, Controller, Post, Request, UseGuards } from "@nestjs/common"; +import { ApiBearerAuth, ApiTags } from "@nestjs/swagger"; +import { RolesGuard } from "../../common/guards"; + +import { UserService } from "./user.service"; +import { UserUpdateTokenAddressDto } from "./user.dto"; + +@ApiBearerAuth() +@ApiTags("User") +@Controller("/user") +export class UserController { + constructor(private readonly userService: UserService) {} + + @UseGuards(RolesGuard) + @Post("/") + public async updateTokenAddress(@Request() req: any, @Body() data: UserUpdateTokenAddressDto): Promise { + return this.userService.update(req.user?.id, data); + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.dto.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.dto.ts new file mode 100644 index 0000000000..fac83d0c50 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.dto.ts @@ -0,0 +1,71 @@ +import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger"; +import { IsEmail, IsEnum, IsOptional, IsString } from "class-validator"; +import { Transform } from "class-transformer"; + +import { SearchDto } from "../../common/collection"; +import { UserStatus, UserType } from "../../common/enums/user"; +import { ValidatePasswordDto } from "../auth/auth.dto"; +import { v4 } from "uuid"; +import { IUser } from "../../common/decorators"; + +export class UserCreateDto extends ValidatePasswordDto { + @ApiProperty() + @IsEmail() + @Transform(({ value }: { value: string }) => value.toLowerCase()) + public email: string; + public type: UserType; + public status: UserStatus; +} + + +export class UserSearchDto extends SearchDto {} + + +export class UserUpdateDto { + @ApiPropertyOptional() + @IsOptional() + @IsEmail() + @Transform(({ value }: { value: string }) => value.toLowerCase()) + public email?: string; + + @ApiPropertyOptional({ + enum: UserStatus, + }) + @IsEnum(UserStatus) + public status?: UserStatus; +} + +export class UserUpdateTokenAddressDto { + @ApiProperty() + @IsString() + public tokenAddress: string; + + public status?: UserStatus; + + public socketId?: string; +} + +export const generateUserCreateDto = (data: Partial = {}): UserCreateDto => { + return Object.assign( + { + password: "human", + confirm: "human", + type: UserType.REQUESTER, + status: UserStatus.ACTIVE, + email: `human+${v4()}@human.com`, + }, + data, + ); +}; + +export const generateTestUser = (data: Partial = {}): Partial => { + return Object.assign( + { + password: "HUMAN", + email: `human+${v4()}@hmt.ai`, + type: UserType.REQUESTER, + status: UserStatus.ACTIVE, + }, + data, + ); +}; diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.entity.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.entity.ts new file mode 100644 index 0000000000..22714388ad --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.entity.ts @@ -0,0 +1,26 @@ +import { Column, Entity, OneToMany } from "typeorm"; +import { Exclude } from "class-transformer"; + +import { NS } from "../../common/constants"; +import { BaseEntity } from "../../database/base.entity"; +import { IUser } from "../../common/decorators"; +import { UserStatus, UserType } from "../../common/enums/user"; + +@Entity({ schema: NS, name: "user" }) +export class UserEntity extends BaseEntity implements IUser { + @Exclude() + @Column({ type: "varchar", select: false }) + public password: string; + + @Column({ type: "varchar", nullable: true, unique: true }) + public email: string; + + @Column({ type: "enum", enum: UserType }) + public type: UserType; + + @Column({ + type: "enum", + enum: UserStatus, + }) + public status: UserStatus; +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.module.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.module.ts new file mode 100644 index 0000000000..172f273d37 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.module.ts @@ -0,0 +1,17 @@ +import { Logger, Module } from "@nestjs/common"; +import { TypeOrmModule } from "@nestjs/typeorm"; +import { ConfigModule } from "@nestjs/config"; + +import { UserService } from "./user.service"; +import { UserEntity } from "./user.entity"; +import { UserController } from "./user.controller"; +import { AuthEntity } from "../auth/auth.entity"; +import { UserReposotory } from "./user.repository"; + +@Module({ + imports: [TypeOrmModule.forFeature([UserEntity, AuthEntity]), ConfigModule], + controllers: [UserController], + providers: [Logger, UserService, UserReposotory], + exports: [UserService], +}) +export class UserModule {} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.repository.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.repository.ts new file mode 100644 index 0000000000..31f069a198 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.repository.ts @@ -0,0 +1,55 @@ +import { Injectable, Logger, NotFoundException } from "@nestjs/common"; +import { InjectRepository } from "@nestjs/typeorm"; +import { FindConditions, FindManyOptions, FindOneOptions, Not, Repository, getRepository } from "typeorm"; + +import { UserEntity } from "./user.entity"; +import { UserCreateDto, UserUpdateDto } from "./user.dto"; +import { ErrorUser } from "../../common/constants/errors"; + +@Injectable() +export class UserReposotory { + private readonly logger = new Logger(UserReposotory.name); + + constructor( + @InjectRepository(UserEntity) + private readonly userEntityRepository: Repository, + ) {} + + public async updateOne( + where: FindConditions, + dto: Partial, + ): Promise { + const userEntity = await this.userEntityRepository.findOne(where); + + if (!userEntity) { + this.logger.log(ErrorUser.NotFound, UserReposotory.name); + throw new NotFoundException(ErrorUser.NotFound); + } + + Object.assign(userEntity, dto); + return userEntity.save(); + } + + public findOne( + where: FindConditions, + options?: FindOneOptions, + ): Promise { + return this.userEntityRepository.findOne({ where, ...options }); + } + + public find(where: FindConditions, options?: FindManyOptions): Promise { + return this.userEntityRepository.find({ + where, + order: { + createdAt: "DESC", + }, + ...options, + }); + } + + public async create(dto: UserCreateDto): Promise { + return this.userEntityRepository + .create(dto) + .save(); + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.seed.module.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.seed.module.ts new file mode 100644 index 0000000000..e88dd43288 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.seed.module.ts @@ -0,0 +1,13 @@ +import { Module } from "@nestjs/common"; +import { TypeOrmModule } from "@nestjs/typeorm"; + +import { UserSeedService } from "./user.seed.service"; +import { UserEntity } from "./user.entity"; +import { UserReposotory } from "./user.repository"; + +@Module({ + imports: [TypeOrmModule.forFeature([UserEntity])], + providers: [UserSeedService, UserReposotory], + exports: [UserSeedService], +}) +export class UserSeedModule {} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.seed.service.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.seed.service.ts new file mode 100644 index 0000000000..3007d116b0 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.seed.service.ts @@ -0,0 +1,33 @@ +import { Injectable } from "@nestjs/common"; +import { InjectRepository } from "@nestjs/typeorm"; +import { Repository } from "typeorm"; +import { subDays } from "date-fns"; + +import { UserEntity } from "./user.entity"; +import { generateTestUser } from "./user.dto"; + +@Injectable() +export class UserSeedService { + constructor( + @InjectRepository(UserEntity) + private readonly userEntityRepository: Repository, + ) {} + + public async setup(): Promise { + const user1 = await this.userEntityRepository.create(generateTestUser()).save(); + + const user2 = await this.userEntityRepository.create(generateTestUser()).save(); + + user2.createdAt = subDays(new Date(), 7); + + await user2.save(); + + return { + users: [user1, user2], + }; + } + + public async tearDown(): Promise { + await this.userEntityRepository.delete({}); + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.serializer.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.serializer.ts new file mode 100644 index 0000000000..c21e56c764 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.serializer.ts @@ -0,0 +1,18 @@ +import { UserStatus, UserType } from "../../common/enums/user"; +import { UserEntity } from "./user.entity"; + +export interface IUserDto { + id: number; + email: string; + status: UserStatus; + type: UserType; +} + +export const userFormatter = (userEntity: UserEntity): IUserDto => { + return { + id: userEntity.id, + email: userEntity.email, + status: userEntity.status, + type: userEntity.type, + }; +}; diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.service.spec.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.service.spec.ts new file mode 100644 index 0000000000..c3c3e9bfe0 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.service.spec.ts @@ -0,0 +1,92 @@ +import { Test } from "@nestjs/testing"; +import { Logger } from "@nestjs/common"; +import { ConfigModule } from "@nestjs/config"; +import { TypeOrmModule } from "@nestjs/typeorm"; +import { v4 } from "uuid"; + +import { DatabaseModule } from "../../database/database.module"; +import { UserService } from "./user.service"; +import { UserSeedModule } from "./user.seed.module"; +import { UserSeedService } from "./user.seed.service"; +import { UserEntity } from "./user.entity"; +import { UserStatus } from "../../common/enums/user"; +import { generateUserCreateDto } from "./user.dto"; + +describe("UserService", () => { + let userService: UserService; + let userSeedService: UserSeedService; + + beforeEach(async () => { + const moduleRef = await Test.createTestingModule({ + imports: [ + ConfigModule.forRoot({ + envFilePath: `.env.${process.env.NODE_ENV as string}`, + }), + DatabaseModule, + TypeOrmModule.forFeature([UserEntity]), + UserSeedModule, + ], + providers: [Logger, UserService, UserSeedService], + }).compile(); + + userService = moduleRef.get(UserService); + userSeedService = moduleRef.get(UserSeedService); + }); + + afterEach(async () => { + await userSeedService.tearDown(); + }); + + describe("createPasswordHash", () => { + it("should generate password hash", () => { + const hash = userService.createPasswordHash("human"); + expect(hash).toEqual("c4639abff90cb9e0a4cbc16472304d58403ec2a5fea17fe23238de50e0ef490e"); + }); + }); + + describe("create", () => { + it("create user (ConflictException lowercase)", async () => { + const entities = await userSeedService.setup(); + return userService + .create(generateUserCreateDto({ email: entities.users[0].email })) + .then(() => fail(new Error())) + .catch(e => { + expect(e.status).toEqual(409); + }); + }); + + it("create user (ConflictException uppercase)", async () => { + const entities = await userSeedService.setup(); + return userService + .create(generateUserCreateDto({ email: entities.users[0].email.toUpperCase() })) + .then(() => fail(new Error())) + .catch(e => { + expect(e.status).toEqual(409); + }); + }); + + it("create user", () => { + return userService.create(generateUserCreateDto()); + }); + }); + + describe("update", () => { + it("should update email", async () => { + const entities = await userSeedService.setup(); + const email = `trejgun+${v4()}@gmail.com`; + const userEntity = await userService.update(entities.users[0].id, { email }); + expect(userEntity.email).toEqual(email); + expect(userEntity.status).toEqual(UserStatus.PENDING); + }); + + it("should NOT update email", async () => { + const entities = await userSeedService.setup(); + const userEntity = await userService.update( + entities.users[0].id, + { email: entities.users[0].email.toUpperCase() }, + ); + expect(userEntity.email).toEqual(entities.users[0].email); + expect(userEntity.status).toEqual(UserStatus.ACTIVE); + }); + }); +}); diff --git a/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.service.ts b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.service.ts new file mode 100644 index 0000000000..4ff263e5d0 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/src/modules/user/user.service.ts @@ -0,0 +1,85 @@ +import { ConflictException, Injectable, Logger, NotFoundException } from "@nestjs/common"; +import { ConfigService } from "@nestjs/config"; +import bcrypt from "bcrypt"; +import { Not } from "typeorm"; + +import { UserEntity } from "./user.entity"; +import { UserStatus, UserType } from "../../common/enums/user"; +import { UserCreateDto, UserUpdateDto } from "./user.dto"; +import { UserReposotory } from "./user.repository"; +import { ValidatePasswordDto } from "../auth/auth.dto"; +import { ErrorUser } from "../../common/constants/errors"; + +@Injectable() +export class UserService { + private readonly logger = new Logger(UserService.name); + + constructor( + private userRepository: UserReposotory, + private readonly configService: ConfigService, + ) {} + + public async update(userId: number, dto: UserUpdateDto): Promise { + return this.userRepository.updateOne({ id: userId }, dto) + } + + public async create(dto: UserCreateDto): Promise { + const { email, password, ...rest } = dto; + + await this.checkEmail(email, 0); + + return this.userRepository + .create({ + ...rest, + email, + password: this.createPasswordHash(password), + type: UserType.REQUESTER, + status: UserStatus.ACTIVE + }); + } + + public async getByCredentials(email: string, password: string): Promise { + const userEntity = await this.userRepository.findOne({ + email, + password: this.createPasswordHash(password), + }, + ); + + if (!userEntity) { + throw new NotFoundException("Invalid email or password"); + } + + return userEntity; + } + + public async getByEmail(email: string): Promise { + return this.userRepository.findOne({ email }); + } + + public updatePassword(userEntity: UserEntity, data: ValidatePasswordDto): Promise { + userEntity.password = this.createPasswordHash(data.password); + return userEntity.save(); + } + + public createPasswordHash(password: string): string { + const passwordSecret = this.configService.get("PASSWORD_SECRET", ""); + return bcrypt.hashSync(password, passwordSecret); + } + + public activate(userEntity: UserEntity): Promise { + userEntity.status = UserStatus.ACTIVE; + return userEntity.save(); + } + + public async checkEmail(email: string, id: number): Promise { + const userEntity = await this.userRepository.findOne({ + email, + id: Not(id), + }); + + if (userEntity) { + this.logger.log(ErrorUser.DuplicateEmail, UserService.name); + throw new ConflictException(ErrorUser.DuplicateEmail); + } + } +} diff --git a/packages/examples/fortune-v2/job-launcher/server/tsconfig.json b/packages/examples/fortune-v2/job-launcher/server/tsconfig.json new file mode 100644 index 0000000000..84d1cdd8d0 --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/tsconfig.json @@ -0,0 +1,29 @@ +{ + "compilerOptions": { + "alwaysStrict": true, + "declaration": true, + "emitDecoratorMetadata": true, + "esModuleInterop": true, + "experimentalDecorators": true, + "lib": ["es2019", "ES2020.Promise"], + "module": "commonjs", + "moduleResolution": "node", + "noImplicitAny": true, + "noImplicitReturns": true, + "noImplicitThis": true, + "noUnusedLocals": false, + "noUnusedParameters": false, + "outDir": "./dist", + "removeComments": true, + "resolveJsonModule": true, + "skipLibCheck": true, + "sourceMap": true, + "strictBindCallApply": true, + "strictFunctionTypes": true, + "strictNullChecks": true, + "strictPropertyInitialization": false, + "target": "es2017" + }, + "include": ["./src", "./scripts"], + "exclude": ["node_modules", "dist", "scripts", "test"] +} \ No newline at end of file diff --git a/packages/examples/fortune-v2/job-launcher/server/tsconfig.test.json b/packages/examples/fortune-v2/job-launcher/server/tsconfig.test.json new file mode 100644 index 0000000000..2b9cd7e21c --- /dev/null +++ b/packages/examples/fortune-v2/job-launcher/server/tsconfig.test.json @@ -0,0 +1,7 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "noUnusedLocals": true, + "noUnusedParameters": true + } +} diff --git a/packages/examples/fortune-v2/package.json b/packages/examples/fortune-v2/package.json new file mode 100644 index 0000000000..de6a1244e4 --- /dev/null +++ b/packages/examples/fortune-v2/package.json @@ -0,0 +1,22 @@ +{ + "private": "true", + "name": "@human-protocol/fortune-v2", + "version": "1.0.0", + "description": "Human Protocol Fortune V2", + "license": "MIT", + "scripts": { + "launcher-server": "cd job-launcher/server && yarn start", + "minio": "docker compose up -d minio-mc", + "postgres": "docker compose up -d postgres", + "docker": "docker compose up -d", + "local": "docker compose down && (concurrently --hide 0 \"yarn docker\" \"yarn launcher-server\")", + "lint": "eslint .", + "lint:fix": "eslint . --fix" + }, + "devDependencies": { + "@human-protocol/core": "workspace:*", + "axios": "^1.1.3", + "hardhat": "^2.12.2", + "web3": "^1.8.0" + } +} diff --git a/yarn.lock b/yarn.lock index ccdc0392fd..18fa0b622e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1933,7 +1933,7 @@ dependencies: "@ethersproject/bignumber" "^5.7.0" -"@ethersproject/contracts@5.7.0": +"@ethersproject/contracts@5.7.0", "@ethersproject/contracts@^5.7.0": version "5.7.0" resolved "https://registry.yarnpkg.com/@ethersproject/contracts/-/contracts-5.7.0.tgz#c305e775abd07e48aa590e1a877ed5c316f8bd1e" integrity sha512-5GJbzEU3X+d33CdfPhcyS+z8MzsTrBGk/sc+G+59+tPa9yFkl6HQ9D6L0QMgNTA9q8dT0XKxxkyp883XsQvbbg== @@ -2014,7 +2014,7 @@ resolved "https://registry.yarnpkg.com/@ethersproject/logger/-/logger-5.7.0.tgz#6ce9ae168e74fecf287be17062b590852c311892" integrity sha512-0odtFdXu/XHtjQXJYA3u9G0G8btm0ND5Cu8M7i5vhEcE8/HmF4Lbdqanwyv4uQTr2tx6b7fQRmgLrsnpQlmnig== -"@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.7.0": +"@ethersproject/networks@5.7.1", "@ethersproject/networks@^5.7.0", "@ethersproject/networks@^5.7.1": version "5.7.1" resolved "https://registry.yarnpkg.com/@ethersproject/networks/-/networks-5.7.1.tgz#118e1a981d757d45ccea6bb58d9fd3d9db14ead6" integrity sha512-n/MufjFYv3yFcUyfhnXotyDlNdFb7onmkSy8aQERi2PjNcnWQ66xXxa3XlS8nCcA8aJKJjIIMNJTC7tu80GwpQ== @@ -2165,7 +2165,7 @@ "@ethersproject/transactions" "^5.7.0" "@ethersproject/wordlists" "^5.7.0" -"@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0": +"@ethersproject/web@5.7.1", "@ethersproject/web@^5.7.0", "@ethersproject/web@^5.7.1": version "5.7.1" resolved "https://registry.yarnpkg.com/@ethersproject/web/-/web-5.7.1.tgz#de1f285b373149bee5928f4eb7bcb87ee5fbb4ae" integrity sha512-Gueu8lSvyjBWL4cYsWsjh6MtMwM0+H4HvqFPZfB6dV8ctbP9zFAO73VG1cMWae0FLPCtz0peKPpZY8/ugJJX2w== @@ -2488,6 +2488,11 @@ resolved "https://registry.yarnpkg.com/@human-protocol/core/-/core-1.0.10.tgz#946bc87cd8f8cf0eae5b410c27d227c0de5d599f" integrity sha512-oANinraKrMEwLwQU3lrE52K7aFKY2BL/6rbWImQDIIcSYGcSGPGayfV4lBHCdboKWvmXMamXSXY1IsHE+GEELw== +"@human-protocol/core@workspace:*": + version "1.1.2" + resolved "https://registry.yarnpkg.com/@human-protocol/core/-/core-1.1.2.tgz#2d8d3c30297b9f22fba75b28b40febed250c97e8" + integrity sha512-DEjMPGPuE/u/EdyvOw3jeHwJDcYowmv8CL+FqTJCuOdEIuSYSpbtM08tMgNaSR7vQEGij+v1qSDjM1bj6jZrBg== + "@humanwhocodes/config-array@^0.11.8": version "0.11.8" resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.11.8.tgz#03595ac2075a4dc0f191cc2131de14fbd7d410b9" @@ -3020,6 +3025,26 @@ dependencies: "@lit-labs/ssr-dom-shim" "^1.0.0" +"@lukeed/csprng@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@lukeed/csprng/-/csprng-1.0.1.tgz#625e93a0edb2c830e3c52ce2d67b9d53377c6a66" + integrity sha512-uSvJdwQU5nK+Vdf6zxcWAY2A8r7uqe+gePwLWzJ+fsQehq18pc0I2hJKwypZ2aLM90+Er9u1xn4iLJPZ+xlL4g== + +"@mapbox/node-pre-gyp@^1.0.10": + version "1.0.10" + resolved "https://registry.yarnpkg.com/@mapbox/node-pre-gyp/-/node-pre-gyp-1.0.10.tgz#8e6735ccebbb1581e5a7e652244cadc8a844d03c" + integrity sha512-4ySo4CjzStuprMwk35H5pPbkymjv1SF3jGLj6rAHp/xT/RF7TL7bd9CTm1xDY49K2qF7jmR/g7k+SkLETP6opA== + dependencies: + detect-libc "^2.0.0" + https-proxy-agent "^5.0.0" + make-dir "^3.1.0" + node-fetch "^2.6.7" + nopt "^5.0.0" + npmlog "^5.0.1" + rimraf "^3.0.2" + semver "^7.3.5" + tar "^6.1.11" + "@metamask/eth-sig-util@^4.0.0": version "4.0.1" resolved "https://registry.yarnpkg.com/@metamask/eth-sig-util/-/eth-sig-util-4.0.1.tgz#3ad61f6ea9ad73ba5b19db780d40d9aae5157088" @@ -3300,6 +3325,112 @@ multiformats "^9.5.4" murmurhash3js-revisited "^3.0.0" +"@nestjs/axios@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@nestjs/axios/-/axios-2.0.0.tgz#2116fad483e232ef102a877b503a9f19926bd102" + integrity sha512-F6oceoQLEn031uun8NiommeMkRIojQqVryxQy/mK7fx0CI0KbgkJL3SloCQcsOD+agoEnqKJKXZpEvL6FNswJg== + +"@nestjs/common@^9.3.9": + version "9.3.9" + resolved "https://registry.yarnpkg.com/@nestjs/common/-/common-9.3.9.tgz#170201ce1c2a8f73bd4babe74b64a2a0b37a95d0" + integrity sha512-GshTD9Xz+wD2em6NyzU4NXw5IXMUmapgDgD+iuj6XL0258hvDwODmNk37mBBnZvTZlqER+krvIUKnS34etqF/A== + dependencies: + uid "2.0.1" + iterare "1.2.1" + tslib "2.5.0" + +"@nestjs/config@^2.3.1": + version "2.3.1" + resolved "https://registry.yarnpkg.com/@nestjs/config/-/config-2.3.1.tgz#6ac151f818db4ccf987c7ff8ef5b2c1f4eeec913" + integrity sha512-Ckzel0NZ9CWhNsLfE1hxfDuxJuEbhQvGxSlmZ1/X8awjRmAA/g3kT6M1+MO1SHj1wMtPyUfd9WpwkiqFbiwQgA== + dependencies: + dotenv "16.0.3" + dotenv-expand "10.0.0" + lodash "4.17.21" + uuid "9.0.0" + +"@nestjs/core@^9.3.9": + version "9.3.9" + resolved "https://registry.yarnpkg.com/@nestjs/core/-/core-9.3.9.tgz#694caf785e0209175479637f11be79a930d0c0d6" + integrity sha512-9g1A1G9eirLXEpH21rc6dKb08zHc2+adhCRz8NW39hbejcsxxD72FApJzt4QBQAKvu862ixt/tdpStnFT7lOSw== + dependencies: + uid "2.0.1" + "@nuxtjs/opencollective" "0.3.2" + fast-safe-stringify "2.1.1" + iterare "1.2.1" + path-to-regexp "3.2.0" + tslib "2.5.0" + +"@nestjs/jwt@^10.0.2": + version "10.0.2" + resolved "https://registry.yarnpkg.com/@nestjs/jwt/-/jwt-10.0.2.tgz#bc049fe1622299e456a849999ebf30cb56ab4dd1" + integrity sha512-MLxjCSbO7C9fN2hst5kpIhnJAgglJmrKppXAXqElB8A9ip3ZuCowMDjjmNWWJyfOzE98NV0E0iEQGE2StMUC+Q== + dependencies: + "@types/jsonwebtoken" "9.0.1" + jsonwebtoken "9.0.0" + +"@nestjs/mapped-types@1.2.2": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@nestjs/mapped-types/-/mapped-types-1.2.2.tgz#d9ddb143776e309dbc1a518ac1607fddac1e140e" + integrity sha512-3dHxLXs3M0GPiriAcCFFJQHoDFUuzTD5w6JDhE7TyfT89YKpe6tcCCIqOZWdXmt9AZjjK30RkHRSFF+QEnWFQg== + +"@nestjs/passport@^9.0.3": + version "9.0.3" + resolved "https://registry.yarnpkg.com/@nestjs/passport/-/passport-9.0.3.tgz#4df0e6de3176e04a5770cb432e58f129c8e49f9e" + integrity sha512-HplSJaimEAz1IOZEu+pdJHHJhQyBOPAYWXYHfAPQvRqWtw4FJF1VXl1Qtk9dcXQX1eKytDtH+qBzNQc19GWNEg== + +"@nestjs/platform-express@^9.3.9": + version "9.3.9" + resolved "https://registry.yarnpkg.com/@nestjs/platform-express/-/platform-express-9.3.9.tgz#557ace8589b54d4ee7bad87a1247a521058395d7" + integrity sha512-f8ja2sYuDGj2QSMmjg05n3WF19wJG5yTiYxRi64nsu5GKL0qLM1LzxNemehkni/knExlvF2bDpbKKpna9nC1JA== + dependencies: + body-parser "1.20.1" + cors "2.8.5" + express "4.18.2" + multer "1.4.4-lts.1" + tslib "2.5.0" + +"@nestjs/schedule@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@nestjs/schedule/-/schedule-2.2.0.tgz#6e6e55648d9fa03dfc861354d00da2985161753b" + integrity sha512-wrDnUONTxBkD6lTWh9ecYk/kvJTbA3PylotjBoRsECmcS1SNvgInFXuL38UnHiFnXM3CHSFnzRLB259Bc1mOdQ== + dependencies: + cron "2.2.0" + uuid "9.0.0" + +"@nestjs/swagger@^6.2.1": + version "6.2.1" + resolved "https://registry.yarnpkg.com/@nestjs/swagger/-/swagger-6.2.1.tgz#38caa76ac00993ddc11a79dd24ab9f4392d2791d" + integrity sha512-9M2vkfJHIzLqDZwvM5TEZO0MxRCvIb0xVy0LsmWwxH1lrb0z/4MhU+r2CWDhBtTccVJrKxVPiU2s3T3b9uUJbg== + dependencies: + "@nestjs/mapped-types" "1.2.2" + js-yaml "4.1.0" + lodash "4.17.21" + path-to-regexp "3.2.0" + swagger-ui-dist "4.15.5" + +"@nestjs/terminus@^9.2.1": + version "9.2.1" + resolved "https://registry.yarnpkg.com/@nestjs/terminus/-/terminus-9.2.1.tgz#f173ba807bbab6ed2ee892e859455553274a725e" + integrity sha512-bPJsxKzqLl1BIs1YFIji20h42VG4ElGqc+lyw7nW+as0DkfjpRYUdyEBQJo6dTAcqRrVxSN2m3wKweBknK3Nxw== + dependencies: + boxen "5.1.2" + check-disk-space "3.3.1" + +"@nestjs/testing@^9.3.9": + version "9.3.9" + resolved "https://registry.yarnpkg.com/@nestjs/testing/-/testing-9.3.9.tgz#f09a5df30cb1725a06f9fddd666543bbeb87eb35" + integrity sha512-+mPvSVvSC2SAkYgZZv1mOI2xsdGc1pmq7/sem7iin/JDoFtlvoGSK+pfZHD3IV3EpYtq1v/8/5gi+UFH9yZnDg== + dependencies: + tslib "2.5.0" + +"@nestjs/typeorm@^9.0.1": + version "9.0.1" + resolved "https://registry.yarnpkg.com/@nestjs/typeorm/-/typeorm-9.0.1.tgz#f78bfc00e71731ea860288e4a03830107daf3d9c" + integrity sha512-A2BgLIPsMtmMI0bPKEf4bmzgFPsnvHqNBx3KkvaJ7hJrBQy0OqYOb+Rr06ifblKWDWS2tUPNrAFQbZjtk3PI+g== + dependencies: + uuid "8.3.2" + "@nicolo-ribaudo/eslint-scope-5-internals@5.1.1-v1": version "5.1.1-v1" resolved "https://registry.yarnpkg.com/@nicolo-ribaudo/eslint-scope-5-internals/-/eslint-scope-5-internals-5.1.1-v1.tgz#dbf733a965ca47b1973177dc0bb6c889edcfb129" @@ -3317,6 +3448,11 @@ resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.2.0.tgz#a3150eeb09cc7ab207ebf6d7b9ad311a9bdbed12" integrity sha512-FZfhjEDbT5GRswV3C6uvLPHMiVD6lQBmpoX5+eSiPaMTXte/IKqI5dykDxzZB/WBeK/CDuQRBWarPdi3FNY2zQ== +"@noble/hashes@^1.2.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@noble/hashes/-/hashes-1.3.0.tgz#085fd70f6d7d9d109671090ccae1d3bec62554a1" + integrity sha512-ilHEACi9DwqJB0pw7kv+Apvh50jiiSyR/cQ3y4W7lOR5mhvn/50FLUfsnfJz0BDZtl/RR16kXvptiv6q1msYZg== + "@noble/secp256k1@1.7.1", "@noble/secp256k1@^1.6.3", "@noble/secp256k1@~1.7.0": version "1.7.1" resolved "https://registry.yarnpkg.com/@noble/secp256k1/-/secp256k1-1.7.1.tgz#b251c70f824ce3ca7f8dc3df08d58f005cc0507c" @@ -3585,6 +3721,15 @@ table "^6.8.0" undici "^5.14.0" +"@nuxtjs/opencollective@0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@nuxtjs/opencollective/-/opencollective-0.3.2.tgz#620ce1044f7ac77185e825e1936115bb38e2681c" + integrity sha512-um0xL3fO7Mf4fDxcqx9KryrB7zgRM5JSlvGN5AGkP6JLM5XEKyjeAiPbNxdXVXQ16isuAhYpvP88NgL2BGd6aA== + dependencies: + chalk "^4.1.0" + consola "^2.15.0" + node-fetch "^2.6.1" + "@openzeppelin/contracts-upgradeable@^4.8.3": version "4.8.3" resolved "https://registry.yarnpkg.com/@openzeppelin/contracts-upgradeable/-/contracts-upgradeable-4.8.3.tgz#6b076a7b751811b90fe3a172a7faeaa603e13a3f" @@ -4080,6 +4225,11 @@ dependencies: antlr4ts "^0.5.0-alpha.4" +"@sqltools/formatter@^1.2.2": + version "1.2.5" + resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.5.tgz#3abc203c79b8c3e90fd6c156a0c62d5403520e12" + integrity sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw== + "@stablelib/aead@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@stablelib/aead/-/aead-1.0.1.tgz#c4b1106df9c23d1b867eb9b276d8f42d5fc4c0c3" @@ -4444,6 +4594,13 @@ dependencies: "@babel/types" "^7.3.0" +"@types/bcrypt@^5.0.0": + version "5.0.0" + resolved "https://registry.yarnpkg.com/@types/bcrypt/-/bcrypt-5.0.0.tgz#a835afa2882d165aff5690893db314eaa98b9f20" + integrity sha512-agtcFKaruL8TmcvqbndlqHPSJgsolhf/qPWchFlgnW1gECTN/nKbFcoFnvKAQRFfKbh+BO6A3SWdJu9t+xF3Lw== + dependencies: + "@types/node" "*" + "@types/bn.js@^4.11.3": version "4.11.6" resolved "https://registry.yarnpkg.com/@types/bn.js/-/bn.js-4.11.6.tgz#c306c70d9358aaea33cd4eda092a742b9505967c" @@ -4517,6 +4674,13 @@ dependencies: "@types/node" "*" +"@types/cookie-parser@^1.4.3": + version "1.4.3" + resolved "https://registry.yarnpkg.com/@types/cookie-parser/-/cookie-parser-1.4.3.tgz#3a01df117c5705cf89a84c876b50c5a1fd427a21" + integrity sha512-CqSKwFwefj4PzZ5n/iwad/bow2hTCh0FlNAeWLtQM3JA/NX/iYagIpWG2cf1bQKQ2c9gU2log5VUCrn7LDOs0w== + dependencies: + "@types/express" "*" + "@types/cors@^2.8.12": version "2.8.13" resolved "https://registry.yarnpkg.com/@types/cors/-/cors-2.8.13.tgz#b8ade22ba455a1b8cb3b5d3f35910fd204f84f94" @@ -4599,7 +4763,14 @@ "@types/qs" "*" "@types/range-parser" "*" -"@types/express@^4.17.13", "@types/express@^4.17.14": +"@types/express-session@^1.17.6": + version "1.17.6" + resolved "https://registry.yarnpkg.com/@types/express-session/-/express-session-1.17.6.tgz#1c8881ba0dc836ffbf1071b2f020d60fcca0f08c" + integrity sha512-L6sB04HVA4HEZo1hDL65JXdZdBJtzZnCiw/P7MnO4w6746tJCNtXlHtzEASyI9ccn9zyOw6IbqQuhVa03VpO4w== + dependencies: + "@types/express" "*" + +"@types/express@*", "@types/express@^4.17.13", "@types/express@^4.17.14", "@types/express@^4.17.17": version "4.17.17" resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.17.tgz#01d5437f6ef9cfa8668e616e13c2f2ac9a491ae4" integrity sha512-Q4FmmuLGBG58btUnfS1c1r/NQdlp3DMfGDGig8WhfpA2YRUtEkxAjkZb0yvplJGYdF1fsQ81iMDcH24sSCNC/Q== @@ -4723,6 +4894,13 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== +"@types/jsonwebtoken@*", "@types/jsonwebtoken@9.0.1": + version "9.0.1" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz#29b1369c4774200d6d6f63135bf3d1ba3ef997a4" + integrity sha512-c5ltxazpWabia/4UzhIoaDcIza4KViOQhdbjRlfcIGVnsE3c3brkz9Z+F/EeJIECOQP7W7US2hNE930cWWkPiw== + dependencies: + "@types/node" "*" + "@types/keyv@^3.1.4": version "3.1.4" resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.4.tgz#3ccdb1c6751b0c7e52300bcdacd5bcbf8faa75b6" @@ -4777,11 +4955,21 @@ resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-10.0.1.tgz#2f4f65bb08bc368ac39c96da7b2f09140b26851b" integrity sha512-/fvYntiO1GeICvqbQ3doGDIP97vWmvFt83GKguJ6prmQM2iXZfFcq6YE8KteFyRtX2/h5Hf91BYvPodJKFYv5Q== -"@types/node@*", "@types/node@>=13.7.0", "@types/node@>=8.1.0", "@types/node@^18.11.9": +"@types/node@*", "@types/node@>=13.7.0", "@types/node@^18.11.9": version "18.15.0" resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.0.tgz#286a65e3fdffd691e170541e6ecb0410b16a38be" integrity sha512-z6nr0TTEOBGkzLGmbypWOGnpSpSIBorEhC4L+4HeQ2iezKCi4f77kyslRwvHeNitymGQ+oFyIWGP96l/DPSV9w== +"@types/node@12.12.54": + version "12.12.54" + resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.54.tgz#a4b58d8df3a4677b6c08bfbc94b7ad7a7a5f82d1" + integrity sha512-ge4xZ3vSBornVYlDnk7yZ0gK6ChHf/CHB7Gl1I0Jhah8DDnEQqBzgohYG4FX4p81TNirSETOiSyn+y1r9/IR6w== + +"@types/node@>=8.1.0": + version "18.13.0" + resolved "https://registry.yarnpkg.com/@types/node/-/node-18.13.0.tgz#0400d1e6ce87e9d3032c19eb6c58205b0d3f7850" + integrity sha512-gC3TazRzGoOnoKAhUx+Q0t8S9Tzs74z7m0ipwGpSqQrleP14hKxP4/JUeEQcD3W1/aIpnWl8pHowI7WokuZpXg== + "@types/node@^10.0.3": version "10.17.60" resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.60.tgz#35f3d6213daed95da7f0f73e75bcc6980e90597b" @@ -4812,6 +5000,38 @@ resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== +"@types/passport-jwt@^3.0.8": + version "3.0.8" + resolved "https://registry.yarnpkg.com/@types/passport-jwt/-/passport-jwt-3.0.8.tgz#c8a95bf7d8f330f2560f1b3d07605e23ac01469a" + integrity sha512-VKJZDJUAHFhPHHYvxdqFcc5vlDht8Q2pL1/ePvKAgqRThDaCc84lSYOTQmnx3+JIkDlN+2KfhFhXIzlcVT+Pcw== + dependencies: + "@types/express" "*" + "@types/jsonwebtoken" "*" + "@types/passport-strategy" "*" + +"@types/passport-strategy@*": + version "0.2.35" + resolved "https://registry.yarnpkg.com/@types/passport-strategy/-/passport-strategy-0.2.35.tgz#e52f5212279ea73f02d9b06af67efe9cefce2d0c" + integrity sha512-o5D19Jy2XPFoX2rKApykY15et3Apgax00RRLf0RUotPDUsYrQa7x4howLYr9El2mlUApHmCMv5CZ1IXqKFQ2+g== + dependencies: + "@types/express" "*" + "@types/passport" "*" + +"@types/passport-twitter@^1.0.37": + version "1.0.37" + resolved "https://registry.yarnpkg.com/@types/passport-twitter/-/passport-twitter-1.0.37.tgz#a7652354e92992283d37b7b6ba4c7329165b6cca" + integrity sha512-/FHODUP6ExYpRFdhVOtbHwVZRmni0kFyOFhOwqg61SoSwcED4c5tkhYu5cJElyhD5jbevRTmgInLFFI5s2hBag== + dependencies: + "@types/express" "*" + "@types/passport" "*" + +"@types/passport@*", "@types/passport@^1.0.12": + version "1.0.12" + resolved "https://registry.yarnpkg.com/@types/passport/-/passport-1.0.12.tgz#7dc8ab96a5e895ec13688d9e3a96920a7f42e73e" + integrity sha512-QFdJ2TiAEoXfEQSNDISJR1Tm51I78CymqcBa8imbjo6dNNu+l2huDxxbDEIoFIwOSKMkOfHEikyDuZ38WwWsmw== + dependencies: + "@types/express" "*" + "@types/pbkdf2@^3.0.0": version "3.1.0" resolved "https://registry.yarnpkg.com/@types/pbkdf2/-/pbkdf2-3.1.0.tgz#039a0e9b67da0cdc4ee5dab865caa6b267bb66b1" @@ -4950,11 +5170,16 @@ resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43" integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA== -"@types/uuid@^9.0.0": +"@types/uuid@^9.0.0", "@types/uuid@^9.0.1": version "9.0.1" resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-9.0.1.tgz#98586dc36aee8dacc98cc396dbca8d0429647aa6" integrity sha512-rFT3ak0/2trgvp4yYZo5iKFEPsET7vKydKF+VRCxlQ9bpheehyAJH89dAkaLEq/j/RZXJIqcgsmPJKUP1Z28HA== +"@types/validator@^13.7.10": + version "13.7.13" + resolved "https://registry.yarnpkg.com/@types/validator/-/validator-13.7.13.tgz#05f2e5663d5d518b04bd69694766807ab20c7288" + integrity sha512-EMfHccxNKXaSxTK6DN0En9WsXa7uR4w3LQtx31f6Z2JjG5hJQeVX5zUYMZoatjZgnoQmRcT94WnNWwi0BzQW6Q== + "@types/ws@^7.4.4": version "7.4.7" resolved "https://registry.yarnpkg.com/@types/ws/-/ws-7.4.7.tgz#f7c390a36f7a0679aa69de2d501319f4f8d9b702" @@ -4988,6 +5213,16 @@ dependencies: "@types/yargs-parser" "*" +"@types/zen-observable@0.8.3": + version "0.8.3" + resolved "https://registry.yarnpkg.com/@types/zen-observable/-/zen-observable-0.8.3.tgz#781d360c282436494b32fe7d9f7f8e64b3118aa3" + integrity sha512-fbF6oTd4sGGy0xjHPKAt+eS2CrxJ3+6gQ3FGcBoIJR2TLAyCkCyI8JqZNy+FeON0AhVgNJoUumVoZQjBFUqHkw== + +"@types/zxcvbn@^4.4.1": + version "4.4.1" + resolved "https://registry.yarnpkg.com/@types/zxcvbn/-/zxcvbn-4.4.1.tgz#46e42cbdcee681b22181478feaf4af2bc4c1abd2" + integrity sha512-3NoqvZC2W5gAC5DZbTpCeJ251vGQmgcWIHQJGq2J240HY6ErQ9aWKkwfoKJlHLx+A83WPNTZ9+3cd2ILxbvr1w== + "@typescript-eslint/eslint-plugin@^5.43.0", "@typescript-eslint/eslint-plugin@^5.5.0": version "5.54.1" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.54.1.tgz#0c5091289ce28372e38ab8d28e861d2dbe1ab29e" @@ -6023,7 +6258,7 @@ amdefine@>=0.0.4: resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" integrity sha512-S2Hw0TtNkMJhIabBwIojKL9YHO5T0n5eNqWJ7Lrlel/zDbftQpxpapi8tZs3X1HWa+u+QeydGmzzNU0m09+Rcg== -ansi-align@^3.0.1: +ansi-align@^3.0.0, ansi-align@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/ansi-align/-/ansi-align-3.0.1.tgz#0cdf12e111ace773a86e9a1fad1225c43cb19a59" integrity sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w== @@ -6134,6 +6369,21 @@ app-module-path@^2.2.0: resolved "https://registry.yarnpkg.com/app-module-path/-/app-module-path-2.2.0.tgz#641aa55dfb7d6a6f0a8141c4b9c0aa50b6c24dd5" integrity sha512-gkco+qxENJV+8vFcDiiFhuoSvRXb2a/QPqpSoWhVz829VNJfOTnELbBmPmNKFxf3xdNnw4DWCkzkDaavcX/1YQ== +app-root-path@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.1.0.tgz#5971a2fc12ba170369a7a1ef018c71e6e47c2e86" + integrity sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA== + +append-field@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-field/-/append-field-1.0.0.tgz#1e3440e915f0b1203d23748e78edd7b9b5b43e56" + integrity sha512-klpgFSWLW1ZEs8svjfb7g4qWY0YS5imI82dTg+QahUvJ8YqAY0P10Uk8tTyh9ZGuYEZEMaeJYCF5BFuX552hsw== + +"aproba@^1.0.3 || ^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-2.0.0.tgz#52520b8ae5b569215b354efc0caa3fe1e45a8adc" + integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== + arch@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" @@ -6144,6 +6394,14 @@ archy@^1.0.0: resolved "https://registry.yarnpkg.com/archy/-/archy-1.0.0.tgz#f9c8c13757cc1dd7bc379ac77b2c62a5c2868c40" integrity sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw== +are-we-there-yet@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-2.0.0.tgz#372e0e7bd279d8e94c653aaa1f67200884bf3e1c" + integrity sha512-Ci/qENmwHnsYo9xKIcUJN5LeDKdJ6R1Z1j9V/J5wyq8nh/mYPEpIKJbBZXtZjG04HiK7zV/p6Vs9952MrMeUIw== + dependencies: + delegates "^1.0.0" + readable-stream "^3.6.0" + arg@5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/arg/-/arg-5.0.2.tgz#c81433cc427c92c4dcf4865142dbca6f15acd59c" @@ -6457,7 +6715,7 @@ axios@^0.27.2: follow-redirects "^1.14.9" form-data "^4.0.0" -axios@^1.1.3, axios@^1.2.2, axios@^1.2.3, axios@^1.2.6, axios@^1.3.3, axios@^1.3.4: +axios@^1.1.3, axios@^1.2.2, axios@^1.2.3, axios@^1.2.6, axios@^1.3.4: version "1.3.4" resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.4.tgz#f5760cefd9cfb51fd2481acf88c05f67c4523024" integrity sha512-toYm+Bsyl6VC5wSkfkbbNB6ROv7KY93PEBBL6xyDczaIHasAiv4wPqQ/c4RjoQzipxRD2W5g21cOqQulZ7rHwQ== @@ -6466,6 +6724,15 @@ axios@^1.1.3, axios@^1.2.2, axios@^1.2.3, axios@^1.2.6, axios@^1.3.3, axios@^1.3 form-data "^4.0.0" proxy-from-env "^1.1.0" +axios@^1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/axios/-/axios-1.3.3.tgz#e7011384ba839b885007c9c9fae1ff23dceb295b" + integrity sha512-eYq77dYIFS77AQlhzEL937yUBSepBfPIe8FcgEDN35vMNZKMrs81pgnyrQpwfy4NF4b4XWX1Zgx7yX+25w8QJA== + dependencies: + follow-redirects "^1.15.0" + form-data "^4.0.0" + proxy-from-env "^1.1.0" + axobject-query@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/axobject-query/-/axobject-query-3.1.1.tgz#3b6e5c6d4e43ca7ba51c5babf99d22a9c68485e1" @@ -6642,6 +6909,11 @@ base64-js@^1.0.2, base64-js@^1.3.1: resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== +base64url@3.x.x: + version "3.0.1" + resolved "https://registry.yarnpkg.com/base64url/-/base64url-3.0.1.tgz#6399d572e2bc3f90a9a8b22d5dbb0a32d33f788d" + integrity sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A== + bcrypt-pbkdf@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" @@ -6649,6 +6921,14 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +bcrypt@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-5.1.0.tgz#bbb27665dbc400480a524d8991ac7434e8529e17" + integrity sha512-RHBS7HI5N5tEnGTmtR/pppX0mmDSBpQ4aCBsj7CEQfYXDcO74A8sIBYcJMuCsis2E81zDxeENYhv66oZwLiA+Q== + dependencies: + "@mapbox/node-pre-gyp" "^1.0.10" + node-addon-api "^5.0.0" + bech32@1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/bech32/-/bech32-1.1.4.tgz#e38c9f37bf179b8eb16ae3a772b40c356d4832e9" @@ -6678,6 +6958,11 @@ bignumber.js@^9.0.0, bignumber.js@^9.0.1, bignumber.js@^9.1.0: resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.1.1.tgz#c4df7dc496bd849d4c9464344c1aa74228b4dac6" integrity sha512-pHm4LsMJ6lzgNGVfZHjMoO8sdoRhOzOH4MLmY65Jg70bpxCKu5iOHNJyfF6OyvYw7t8Fpf35RuzUyqnQsj8Vig== +bignumber.js@~9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.2.tgz#71c6c6bed38de64e24a65ebe16cfcf23ae693673" + integrity sha512-GAcQvbpsM0pUb0zw1EI0KhQEZ+lRwR5fYaAp3vPOYuP7aDvGy6cVN6XHLauvF8SOga2y0dcLcjt3iQDTSEliyw== + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.2.0.tgz#75f502eeaf9ffde42fc98829645be4ea76bd9e2d" @@ -6719,6 +7004,13 @@ bindings@^1.3.0, bindings@^1.5.0: dependencies: file-uri-to-path "1.0.0" +bip39@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-3.1.0.tgz#c55a418deaf48826a6ceb34ac55b3ee1577e18a3" + integrity sha512-c9kiwdk45Do5GL0vJMe7tS95VjCii65mYAH7DfWl3uW8AVzXKQVUm64i3hzVybBDMp9r7j9iNxR85+ul8MdN/A== + dependencies: + "@noble/hashes" "^1.2.0" + bip66@^1.1.5: version "1.1.5" resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" @@ -6835,7 +7127,7 @@ body-parser@1.20.1: type-is "~1.6.18" unpipe "1.0.0" -body-parser@^1.16.0, body-parser@^1.20.0: +body-parser@^1.16.0, body-parser@^1.20.0, body-parser@^1.20.2: version "1.20.2" resolved "https://registry.yarnpkg.com/body-parser/-/body-parser-1.20.2.tgz#6feb0e21c4724d06de7ff38da36dad4f57a747fd" integrity sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA== @@ -6880,6 +7172,20 @@ borsh@^0.7.0: bs58 "^4.0.0" text-encoding-utf-8 "^1.0.2" +boxen@5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/boxen/-/boxen-5.1.2.tgz#788cb686fc83c1f486dfa8a40c68fc2b831d2b50" + integrity sha512-9gYgQKXx+1nP8mP7CzFyaUARhg7D3n1dF/FnErWmu9l6JvGpNUN278h0aSb+QjoiKSWG+iZ3uHrcqk0qrY9RQQ== + dependencies: + ansi-align "^3.0.0" + camelcase "^6.2.0" + chalk "^4.1.0" + cli-boxes "^2.2.1" + string-width "^4.2.2" + type-fest "^0.20.2" + widest-line "^3.1.0" + wrap-ansi "^7.0.0" + boxen@7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-7.0.0.tgz#9e5f8c26e716793fc96edcf7cf754cdf5e3fbf32" @@ -7077,6 +7383,11 @@ buffer-crc32@^0.2.13: resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + buffer-fill@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" @@ -7097,6 +7408,11 @@ buffer-to-arraybuffer@^0.0.5: resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a" integrity sha512-3dthu5CYiVB1DEJp61FtApNnNndTckcqe4pFcLdvHtrpG+kcyekCJKg4MRiDcFW7A6AODnXB9U4dwQiCW5kzJQ== +buffer-writer@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/buffer-writer/-/buffer-writer-2.0.0.tgz#ce7eb81a38f7829db09c873f2fbb792c0c98ec04" + integrity sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw== + buffer-xor@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" @@ -7152,7 +7468,7 @@ builtin-status-codes@^3.0.0: resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" integrity sha512-HpGFw18DgFWlncDfjTa2rcQ4W88O1mC8e8yZ2AvQY5KDaktSTwo+KRf6nHK6FRI5FyRyb/5T6+TSxfP7QyGsmQ== -busboy@^1.6.0: +busboy@^1.0.0, busboy@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== @@ -7348,6 +7664,11 @@ char-regex@^1.0.2: resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" integrity sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA== +check-disk-space@3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/check-disk-space/-/check-disk-space-3.3.1.tgz#10c4c8706fdd16d3e5c3572a16aa95efd0b4d40b" + integrity sha512-iOrT8yCZjSnyNZ43476FE2rnssvgw5hnuwOM0hm8Nj1qa0v4ieUUEbCyxxsEliaoDUb/75yCOL71zkDiDBLbMQ== + check-error@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/check-error/-/check-error-1.0.2.tgz#574d312edd88bb5dd8912e9286dd6c0aed4aac82" @@ -7468,6 +7789,20 @@ class-is@^1.1.0: resolved "https://registry.yarnpkg.com/class-is/-/class-is-1.1.0.tgz#9d3c0fba0440d211d843cec3dedfa48055005825" integrity sha512-rhjH9AG1fvabIDoGRVH587413LPjTZgmDF9fOFCbFJQV4yuocX1mHxxvXI4g3cGwbVY9wAYIoKlg1N79frJKQw== +class-transformer@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/class-transformer/-/class-transformer-0.5.1.tgz#24147d5dffd2a6cea930a3250a677addf96ab336" + integrity sha512-SQa1Ws6hUbfC98vKGxZH3KFY0Y1lm5Zm0SY8XX9zbK7FJCyVEac3ATW0RIpwzW+oOfmHE5PMPufDG9hCfoEOMw== + +class-validator@^0.14.0: + version "0.14.0" + resolved "https://registry.yarnpkg.com/class-validator/-/class-validator-0.14.0.tgz#40ed0ecf3c83b2a8a6a320f4edb607be0f0df159" + integrity sha512-ct3ltplN8I9fOwUd8GrP8UQixwff129BkEtuWDKL5W45cQuLd19xqmTLu5ge78YDm/fdje6FMt0hGOhl0lii3A== + dependencies: + "@types/validator" "^13.7.10" + libphonenumber-js "^1.10.14" + validator "^13.7.0" + classic-level@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/classic-level/-/classic-level-1.2.0.tgz#2d52bdec8e7a27f534e67fdeb890abef3e643c27" @@ -7489,6 +7824,11 @@ clean-stack@^2.0.0: resolved "https://registry.yarnpkg.com/clean-stack/-/clean-stack-2.2.0.tgz#ee8472dbb129e727b31e8a10a427dee9dfe4008b" integrity sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A== +cli-boxes@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" + integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== + cli-boxes@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-3.0.0.tgz#71a10c716feeba005e4504f36329ef0b17cf3145" @@ -7512,6 +7852,18 @@ cli-cursor@^3.1.0: dependencies: restore-cursor "^3.1.0" +cli-highlight@^2.1.11: + version "2.1.11" + resolved "https://registry.yarnpkg.com/cli-highlight/-/cli-highlight-2.1.11.tgz#49736fa452f0aaf4fae580e30acb26828d2dc1bf" + integrity sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg== + dependencies: + chalk "^4.0.0" + highlight.js "^10.7.1" + mz "^2.4.0" + parse5 "^5.1.1" + parse5-htmlparser2-tree-adapter "^6.0.0" + yargs "^16.0.0" + cli-spinners@^2.2.0: version "2.7.0" resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.7.0.tgz#f815fd30b5f9eaac02db604c7a231ed7cb2f797a" @@ -7662,6 +8014,11 @@ color-string@^1.6.0: color-name "^1.0.0" simple-swizzle "^0.2.2" +color-support@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/color-support/-/color-support-1.1.3.tgz#93834379a1cc9a0c61f82f52f0d04322251bd5a2" + integrity sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg== + color@^3.1.3: version "3.2.1" resolved "https://registry.yarnpkg.com/color/-/color-3.2.1.tgz#3544dc198caf4490c3ecc9a790b54fe9ff45e164" @@ -7775,7 +8132,7 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -concat-stream@^1.6.0, concat-stream@^1.6.2, concat-stream@~1.6.2: +concat-stream@^1.5.2, concat-stream@^1.6.0, concat-stream@^1.6.2, concat-stream@~1.6.2: version "1.6.2" resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== @@ -7826,11 +8183,21 @@ confusing-browser-globals@^1.0.11: resolved "https://registry.yarnpkg.com/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz#ae40e9b57cdd3915408a2805ebd3a5585608dc81" integrity sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA== +consola@^2.15.0: + version "2.15.3" + resolved "https://registry.yarnpkg.com/consola/-/consola-2.15.3.tgz#2e11f98d6a4be71ff72e0bdf07bd23e12cb61550" + integrity sha512-9vAdYbHj6x2fLKC4+oPH0kFzY/orMZyG2Aj+kNylHxKGJ/Ed4dpNyAQYwJOdqO4zdM7XpVHmyejQDcQHrnuXbw== + console-browserify@^1.1.0: version "1.2.0" resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.2.0.tgz#67063cef57ceb6cf4993a2ab3a55840ae8c49336" integrity sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA== +console-control-strings@^1.0.0, console-control-strings@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== + constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -7872,21 +8239,34 @@ convert-source-map@^2.0.0: resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-2.0.0.tgz#4b560f649fc4e918dd0ab75cf4961e8bc882d82a" integrity sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg== +cookie-parser@^1.4.6: + version "1.4.6" + resolved "https://registry.yarnpkg.com/cookie-parser/-/cookie-parser-1.4.6.tgz#3ac3a7d35a7a03bbc7e365073a26074824214594" + integrity sha512-z3IzaNjdwUC2olLIB5/ITd0/setiaFMLYiZJle7xg5Fe9KWAceil7xszYfHHBtDFYLSgJduS2Ty0P1uJdPDJeA== + dependencies: + cookie "0.4.1" + cookie-signature "1.0.6" + cookie-signature@1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" integrity sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ== -cookie@0.5.0, cookie@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" - integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookie@0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.1.tgz#afd713fe26ebd21ba95ceb61f9a8116e50a537d1" + integrity sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA== -cookie@^0.4.1: +cookie@0.4.2, cookie@^0.4.1: version "0.4.2" resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.4.2.tgz#0e41f24de5ecf317947c82fc789e06a884824432" integrity sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA== +cookie@0.5.0, cookie@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.5.0.tgz#d1f5d71adec6558c58f389987c366aa47e994f8b" + integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== + copy-to-clipboard@^3.3.3: version "3.3.3" resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz#55ac43a1db8ae639a4bd99511c148cdd1b83a1b0" @@ -7911,7 +8291,7 @@ core-util-is@~1.0.0: resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== -cors@^2.8.1, cors@^2.8.5: +cors@2.8.5, cors@^2.8.1, cors@^2.8.5: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== @@ -8003,6 +8383,13 @@ create-require@^1.1.0, create-require@^1.1.1: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== +cron@2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cron/-/cron-2.2.0.tgz#605ae5048e9715a22db12e9fe2563a92740b9fed" + integrity sha512-GPiI3OgMv83XRtEUc2gUdaLvJhO3XbLN288layOBkDTupg0RK5IECNGpkykIMHg+muVR2bxt29b0xvCAcBrjYQ== + dependencies: + luxon "^3.2.1" + cross-fetch@^3.1.4, cross-fetch@^3.1.5: version "3.1.5" resolved "https://registry.yarnpkg.com/cross-fetch/-/cross-fetch-3.1.5.tgz#e1389f44d9e7ba767907f7af8454787952ab534f" @@ -8420,6 +8807,11 @@ delayed-stream@~1.0.0: resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" integrity sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ== +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== + delete-empty@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/delete-empty/-/delete-empty-3.0.0.tgz#f8040f2669f26fa7060bc2304e9859c593b685e8" @@ -8435,7 +8827,7 @@ delimit-stream@0.1.0: resolved "https://registry.yarnpkg.com/delimit-stream/-/delimit-stream-0.1.0.tgz#9b8319477c0e5f8aeb3ce357ae305fc25ea1cd2b" integrity sha512-a02fiQ7poS5CnjiJBAsjGLPp5EwVoGHNeu9sziBd9huppRfsAFIpv5zNLv0V1gbop53ilngAf5Kf331AwcoRBQ== -depd@2.0.0, depd@^2.0.0: +depd@2.0.0, depd@^2.0.0, depd@~2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/depd/-/depd-2.0.0.tgz#b696163cc757560d09cf22cc8fad1571b79e76df" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -8458,6 +8850,11 @@ detect-browser@5.3.0, detect-browser@^5.3.0: resolved "https://registry.yarnpkg.com/detect-browser/-/detect-browser-5.3.0.tgz#9705ef2bddf46072d0f7265a1fe300e36fe7ceca" integrity sha512-53rsFbGdwMwlF7qvCt0ypLM5V5/Mbl0szB7GPN8y9NCcbknYOeVVXdrXEq+90IwAfrrzt6Hd+u2E2ntakICU8w== +detect-libc@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-2.0.1.tgz#e1897aa88fa6ad197862937fbc0441ef352ee0cd" + integrity sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w== + detect-newline@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-3.1.0.tgz#576f5dfc63ae1a192ff192d8ad3af6308991b651" @@ -8665,6 +9062,11 @@ dotenv-cli@^6.0.0: dotenv-expand "^8.0.1" minimist "^1.2.5" +dotenv-expand@10.0.0: + version "10.0.0" + resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-10.0.0.tgz#12605d00fb0af6d0a592e6558585784032e4ef37" + integrity sha512-GopVGCpVS1UKH75VKHGuQFqS1Gusej0z4FyQkPdwjil2gNIv+LNsqBlboOzpJFZKVT95GkCyWJbBSdFEFUWI2A== + dotenv-expand@^8.0.1: version "8.0.3" resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-8.0.3.tgz#29016757455bcc748469c83a19b36aaf2b83dd6e" @@ -8675,11 +9077,16 @@ dotenv-expand@^9.0.0: resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-9.0.0.tgz#1fd37e2cd63ea0b5f7389fb87256efc38b035b26" integrity sha512-uW8Hrhp5ammm9x7kBLR6jDfujgaDarNA02tprvZdyrJ7MpdzD1KyrIHG4l+YoC2fJ2UcdFdNWNWIjt+sexBHJw== -dotenv@^16.0.0, dotenv@^16.0.3: +dotenv@16.0.3, dotenv@^16.0.0, dotenv@^16.0.3: version "16.0.3" resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.0.3.tgz#115aec42bac5053db3c456db30cc243a5a836a07" integrity sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ== +dotenv@^8.2.0: + version "8.6.0" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.6.0.tgz#061af664d19f7f4d8fc6e4ff9b584ce237adcb8b" + integrity sha512-IrPdXQsk2BbzvCBGBOTmmSH5SodmqZNt4ERAZDmW4CT+tL8VtvinqywuANaFu4bOMWki16nqf0e4oC0QIaDr/g== + drbg.js@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/drbg.js/-/drbg.js-1.0.1.tgz#3e36b6c42b37043823cdbc332d58f31e2445480b" @@ -8694,6 +9101,11 @@ dset@^3.1.2: resolved "https://registry.yarnpkg.com/dset/-/dset-3.1.2.tgz#89c436ca6450398396dc6538ea00abc0c54cd45a" integrity sha512-g/M9sqy3oHe477Ar4voQxWtaPIFw1jTdKZuomOjhCcBx9nHUNn0pu6NopuFFrTh/TRZIKEj+76vLWFu9BNKk+Q== +duplexer@~0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.2.tgz#3abe43aef3835f8ae077d136ddce0f276b0400e6" + integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== + duplexify@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-4.1.2.tgz#18b4f8d28289132fa0b9573c898d9f903f81c7b0" @@ -8717,6 +9129,13 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz#ae0f0fa2d85045ef14a817daa3ce9acd0489e5bf" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" @@ -9293,6 +9712,11 @@ eslint-config-react-app@^7.0.1: eslint-plugin-react-hooks "^4.3.0" eslint-plugin-testing-library "^5.0.1" +eslint-config-standard@^17.0.0: + version "17.0.0" + resolved "https://registry.yarnpkg.com/eslint-config-standard/-/eslint-config-standard-17.0.0.tgz#fd5b6cf1dcf6ba8d29f200c461de2e19069888cf" + integrity sha512-/2ks1GKyqSOkH7JFvXJicu0iMpoojkwB+f5Du/1SC0PtBL+s8v30k9njRZ21pm2drKYm2342jFnGWzttxPmZVg== + eslint-import-resolver-node@^0.3.7: version "0.3.7" resolved "https://registry.yarnpkg.com/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.7.tgz#83b375187d412324a1963d84fa664377a23eb4d7" @@ -9302,7 +9726,18 @@ eslint-import-resolver-node@^0.3.7: is-core-module "^2.11.0" resolve "^1.22.1" -eslint-import-resolver-typescript@^3.5.2, eslint-import-resolver-typescript@^3.5.3: +eslint-import-resolver-ts@^0.4.2: + version "0.4.2" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-ts/-/eslint-import-resolver-ts-0.4.2.tgz#cd1a4a31144d15b5b6ec7aa88920df4b0e07a385" + integrity sha512-M5WH0xJ3nnwSZZ8f6J550elDmsf/86mau66irHm+qBr5n0soqfuKqr41Qd6oZNBCY6FoSAkiLgnVFEvXAoBvZA== + dependencies: + debug "^4.1.1" + is-glob "^4.0.1" + resolve "^1.12.0" + tiny-glob "^0.2.6" + tsconfig-paths "^3.9.0" + +eslint-import-resolver-typescript@^3.5.2: version "3.5.3" resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.3.tgz#db5ed9e906651b7a59dd84870aaef0e78c663a05" integrity sha512-njRcKYBc3isE42LaTcJNVANR3R99H9bAxBDMNDr2W7yq5gYPxbU3MkdhsQukxZ/Xg9C2vcyLlDsbKfRDg0QvCQ== @@ -9315,6 +9750,20 @@ eslint-import-resolver-typescript@^3.5.2, eslint-import-resolver-typescript@^3.5 is-glob "^4.0.3" synckit "^0.8.4" +eslint-import-resolver-typescript@^3.5.3: + version "3.5.5" + resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.5.tgz#0a9034ae7ed94b254a360fbea89187b60ea7456d" + integrity sha512-TdJqPHs2lW5J9Zpe17DZNQuDnox4xo2o+0tE7Pggain9Rbc19ik8kFtXdxZ250FVx2kF4vlt2RSf4qlUpG7bhw== + dependencies: + debug "^4.3.4" + enhanced-resolve "^5.12.0" + eslint-module-utils "^2.7.4" + get-tsconfig "^4.5.0" + globby "^13.1.3" + is-core-module "^2.11.0" + is-glob "^4.0.3" + synckit "^0.8.5" + eslint-import-resolver-typescript@^3.5.4: version "3.5.4" resolved "https://registry.yarnpkg.com/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.5.4.tgz#7370c326c3c08f0c1839c592d79d20b704de15d4" @@ -9335,6 +9784,14 @@ eslint-module-utils@^2.7.4: dependencies: debug "^3.2.7" +eslint-plugin-es@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-3.0.1.tgz#75a7cdfdccddc0589934aeeb384175f221c57893" + integrity sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ== + dependencies: + eslint-utils "^2.0.0" + regexpp "^3.0.0" + eslint-plugin-flowtype@^8.0.3: version "8.0.3" resolved "https://registry.yarnpkg.com/eslint-plugin-flowtype/-/eslint-plugin-flowtype-8.0.3.tgz#e1557e37118f24734aa3122e7536a038d34a4912" @@ -9400,6 +9857,18 @@ eslint-plugin-jsx-a11y@^6.5.1: object.fromentries "^2.0.6" semver "^6.3.0" +eslint-plugin-node@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-11.1.0.tgz#c95544416ee4ada26740a30474eefc5402dc671d" + integrity sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g== + dependencies: + eslint-plugin-es "^3.0.0" + eslint-utils "^2.0.0" + ignore "^5.1.1" + minimatch "^3.0.4" + resolve "^1.10.1" + semver "^6.1.0" + eslint-plugin-prettier@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz#651cbb88b1dab98bfd42f017a12fa6b2d993f94b" @@ -9407,6 +9876,11 @@ eslint-plugin-prettier@^4.2.1: dependencies: prettier-linter-helpers "^1.0.0" +eslint-plugin-promise@^6.1.1: + version "6.1.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz#269a3e2772f62875661220631bd4dafcb4083816" + integrity sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig== + eslint-plugin-react-hooks@^4.3.0, eslint-plugin-react-hooks@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz#4c3e697ad95b77e93f8646aaa1630c1ba607edd3" @@ -9433,6 +9907,11 @@ eslint-plugin-react@^7.27.1, eslint-plugin-react@^7.31.10, eslint-plugin-react@^ semver "^6.3.0" string.prototype.matchall "^4.0.8" +eslint-plugin-standard@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-standard/-/eslint-plugin-standard-5.0.0.tgz#c43f6925d669f177db46f095ea30be95476b1ee4" + integrity sha512-eSIXPc9wBM4BrniMzJRBm2uoVuXz2EPa+NXPk2+itrVt+r5SbKFERx/IgrK/HmfjddyKVz2f+j+7gBRvu19xLg== + eslint-plugin-testing-library@^5.0.1: version "5.10.2" resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-5.10.2.tgz#12f231ad9b52b6aef45c801fd00aa129a932e0c2" @@ -9456,7 +9935,7 @@ eslint-scope@^7.1.1: esrecurse "^4.3.0" estraverse "^5.2.0" -eslint-utils@^2.1.0: +eslint-utils@^2.0.0, eslint-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/eslint-utils/-/eslint-utils-2.1.0.tgz#d2de5e03424e707dc10c74068ddedae708741b27" integrity sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg== @@ -9842,6 +10321,14 @@ ethereum-cryptography@^1.0.3: "@scure/bip32" "1.1.5" "@scure/bip39" "1.1.1" +ethereum-types@^3.7.1: + version "3.7.1" + resolved "https://registry.yarnpkg.com/ethereum-types/-/ethereum-types-3.7.1.tgz#8fa75e5d9f5da3c85535ea0d4bcd2614b1d650a8" + integrity sha512-EBQwTGnGZQ9oHK7Za3DFEOxiElksRCoZECkk418vHiE2d59lLSejDZ1hzRVphtFjAu5YqONz4/XuAYdMBg+gWA== + dependencies: + "@types/node" "12.12.54" + bignumber.js "~9.0.2" + ethereumjs-abi@^0.6.8: version "0.6.8" resolved "https://registry.yarnpkg.com/ethereumjs-abi/-/ethereumjs-abi-0.6.8.tgz#71bc152db099f70e62f108b7cdfca1b362c6fcae" @@ -9949,6 +10436,19 @@ event-emitter@^0.3.5: d "1" es5-ext "~0.10.14" +event-stream@=3.3.4: + version "3.3.4" + resolved "https://registry.yarnpkg.com/event-stream/-/event-stream-3.3.4.tgz#4ab4c9a0f5a54db9338b4c34d86bfce8f4b35571" + integrity sha512-QHpkERcGsR0T7Qm3HNJSyXKEEj8AHNxkY3PK8TS2KJvQ7NiSHe3DDpwVKKtoYprL/AreyzFBeIkBIWChAqn60g== + dependencies: + duplexer "~0.1.1" + from "~0" + map-stream "~0.1.0" + pause-stream "0.0.11" + split "0.3" + stream-combiner "~0.0.4" + through "~2.3.1" + event-target-shim@^5.0.0: version "5.0.1" resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" @@ -10048,7 +10548,21 @@ express-rate-limit@^6.7.0: resolved "https://registry.yarnpkg.com/express-rate-limit/-/express-rate-limit-6.7.0.tgz#6aa8a1bd63dfe79702267b3af1161a93afc1d3c2" integrity sha512-vhwIdRoqcYB/72TK3tRZI+0ttS8Ytrk24GfmsxDXK9o9IhHNO5bXRiXQSExPQ4GbaE5tvIS7j1SGrxsuWs+sGA== -express@^4.14.0, express@^4.17.1, express@^4.18.1: +express-session@^1.17.3: + version "1.17.3" + resolved "https://registry.yarnpkg.com/express-session/-/express-session-1.17.3.tgz#14b997a15ed43e5949cb1d073725675dd2777f36" + integrity sha512-4+otWXlShYlG1Ma+2Jnn+xgKUZTMJ5QD3YvfilX3AcocOAbIkVylSWEklzALe/+Pu4qV6TYBj5GwOBFfdKqLBw== + dependencies: + cookie "0.4.2" + cookie-signature "1.0.6" + debug "2.6.9" + depd "~2.0.0" + on-headers "~1.0.2" + parseurl "~1.3.3" + safe-buffer "5.2.1" + uid-safe "~2.1.5" + +express@4.18.2, express@^4.14.0, express@^4.17.1, express@^4.18.1, express@^4.18.2: version "4.18.2" resolved "https://registry.yarnpkg.com/express/-/express-4.18.2.tgz#3fabe08296e930c796c19e3c516979386ba9fd59" integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== @@ -10202,7 +10716,7 @@ fast-redact@^3.0.0, fast-redact@^3.1.1: resolved "https://registry.yarnpkg.com/fast-redact/-/fast-redact-3.1.2.tgz#d58e69e9084ce9fa4c1a6fa98a3e1ecf5d7839aa" integrity sha512-+0em+Iya9fKGfEQGcd62Yv6onjBmmhV1uh86XVfOU8VwAe6kaFdQCWI9s0/Nnugx5Vd9tdbZ7e6gE2tR9dzXdw== -fast-safe-stringify@^2.0.6, fast-safe-stringify@^2.1.1: +fast-safe-stringify@2.1.1, fast-safe-stringify@^2.0.6, fast-safe-stringify@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz#c406a83b6e70d9e35ce3b30a81141df30aeba884" integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== @@ -10487,6 +11001,11 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q== +from@~0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/from/-/from-0.1.7.tgz#83c60afc58b9c56997007ed1a768b3ab303a44fe" + integrity sha512-twe20eF1OxVxp/ML/kq2p1uc6KvFK/+vs8WjEbeKmV2He22MKm7YF2ANIt+EOqhJ5L3K/SuuPhk0hWQDjOM23g== + fs-constants@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/fs-constants/-/fs-constants-1.0.0.tgz#6be0de9be998ce16af8afc24497b9ee9b7ccd9ad" @@ -10621,6 +11140,21 @@ functions-have-names@^1.2.2: resolved "https://registry.yarnpkg.com/functions-have-names/-/functions-have-names-1.2.3.tgz#0404fe4ee2ba2f607f0e0ec3c80bae994133b834" integrity sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ== +gauge@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-3.0.2.tgz#03bf4441c044383908bcfa0656ad91803259b395" + integrity sha512-+5J6MS/5XksCuXq++uFRsnUd7Ovu1XenbeuIuNRJxYWjgQbPuFhT14lAvsWfqfAmnwluf1OwMjz39HjfLPci0Q== + dependencies: + aproba "^1.0.3 || ^2.0.0" + color-support "^1.1.2" + console-control-strings "^1.0.0" + has-unicode "^2.0.1" + object-assign "^4.1.1" + signal-exit "^3.0.0" + string-width "^4.2.3" + strip-ansi "^6.0.1" + wide-align "^1.1.2" + gensync@^1.0.0-beta.2: version "1.0.0-beta.2" resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0" @@ -10801,6 +11335,16 @@ glob@^8.0.0, glob@^8.0.3: minimatch "^5.0.1" once "^1.3.0" +glob@^9.2.0: + version "9.2.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-9.2.1.tgz#f47e34e1119e7d4f93a546e75851ba1f1e68de50" + integrity sha512-Pxxgq3W0HyA3XUvSXcFhRSs+43Jsx0ddxcFrbjxNGkL2Ak5BAUBxLqI5G6ADDeCHLfzzXFhe0b1yYcctGmytMA== + dependencies: + fs.realpath "^1.0.0" + minimatch "^7.4.1" + minipass "^4.2.4" + path-scurry "^1.6.1" + global-modules@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" @@ -11237,6 +11781,11 @@ has-tostringtag@^1.0.0: dependencies: has-symbols "^1.0.2" +has-unicode@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + integrity sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ== + has@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" @@ -11279,6 +11828,11 @@ he@1.2.0, he@^1.2.0: resolved "https://registry.yarnpkg.com/heap/-/heap-0.2.7.tgz#1e6adf711d3f27ce35a81fe3b7bd576c2260a8fc" integrity sha512-2bsegYkkHO+h/9MGbn6KWcE45cHZgPANo5LXF7EvWdT0yT2EguSVO1nDgU5c8+ZOPwp2vMNa7YFsJhVcDR9Sdg== +helmet@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/helmet/-/helmet-6.0.1.tgz#52ec353638b2e87f14fe079d142b368ac11e79a4" + integrity sha512-8wo+VdQhTMVBMCITYZaGTbE4lvlthelPYSvoyNvk4RECTmrVjMerp9RfUOQXZWLvCcAn1pKj7ZRxK4lI9Alrcw== + help-me@^4.0.1: version "4.2.0" resolved "https://registry.yarnpkg.com/help-me/-/help-me-4.2.0.tgz#50712bfd799ff1854ae1d312c36eafcea85b0563" @@ -11297,6 +11851,11 @@ hi-base32@~0.5.0: resolved "https://registry.yarnpkg.com/hi-base32/-/hi-base32-0.5.1.tgz#1279f2ddae2673219ea5870c2121d2a33132857e" integrity sha512-EmBBpvdYh/4XxsnUybsPag6VikPYnN30td+vQk+GI3qpahVEG9+gTkG0aXVxTjBqQ5T6ijbWIu77O+C5WFWsnA== +highlight.js@^10.7.1: + version "10.7.3" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-10.7.3.tgz#697272e3991356e40c3cac566a74eef681756531" + integrity sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A== + hmac-drbg@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" @@ -12454,6 +13013,11 @@ iterable-ndjson@^1.1.0: dependencies: string_decoder "^1.2.0" +iterare@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/iterare/-/iterare-1.2.1.tgz#139c400ff7363690e33abffa33cbba8920f00042" + integrity sha512-RKYVTCjAnRthyJes037NX/IiqeidgN1xc3j1RjFfECFp28A1GVwK9nA+i0rJPaHqSZwygLzRnFlzUuHFoWWy+Q== + jake@^10.8.5: version "10.8.5" resolved "https://registry.yarnpkg.com/jake/-/jake-10.8.5.tgz#f2183d2c59382cb274226034543b9c03b8164c46" @@ -13335,7 +13899,7 @@ js-yaml@3.x, js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" -js-yaml@4.1.0, js-yaml@^4.1.0: +js-yaml@4.1.0, js-yaml@^4.0.0, js-yaml@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== @@ -13589,6 +14153,16 @@ jsonschema@^1.2.4: resolved "https://registry.yarnpkg.com/jsonschema/-/jsonschema-1.4.1.tgz#cc4c3f0077fb4542982973d8a083b6b34f482dab" integrity sha512-S6cATIPVv1z0IlxdN+zUk5EPjkGCdnhN4wVSBlvoUO1tOLJootbo9CquNJmbIh4yikWHiUedhRYrNPn1arpEmQ== +jsonwebtoken@9.0.0, jsonwebtoken@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz#d0faf9ba1cc3a56255fe49c0961a67e520c1926d" + integrity sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw== + dependencies: + jws "^3.2.2" + lodash "^4.17.21" + ms "^2.1.1" + semver "^7.3.8" + jsprim@^1.2.2: version "1.4.2" resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.2.tgz#712c65533a15c878ba59e9ed5f0e26d5b77c5feb" @@ -13632,6 +14206,23 @@ just-map-keys@^1.1.0: resolved "https://registry.yarnpkg.com/just-map-keys/-/just-map-keys-1.2.1.tgz#ef6e16133b7d34329962dfae9101d581abb1b143" integrity sha512-Dmyz1Cy2SWM+PpqDPB1kdDglyexdzMthnAsvOIE9w4OPj8NDRuY1mh20x/JfG5w6fCGw9F0WmcofJhYZ4MiuyA== +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.4.1.tgz#743c32985cb9e98655530d53641b66c8645b039a" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/jws/-/jws-3.2.2.tgz#001099f3639468c9414000e99995fa52fb478304" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + keccak@^3.0.0, keccak@^3.0.1, keccak@^3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/keccak/-/keccak-3.0.3.tgz#4bc35ad917be1ef54ff246f904c2bbbf9ac61276" @@ -13781,6 +14372,11 @@ libp2p-crypto@~0.16.1: tweetnacl "^1.0.0" ursa-optional "~0.10.0" +libphonenumber-js@^1.10.14: + version "1.10.21" + resolved "https://registry.yarnpkg.com/libphonenumber-js/-/libphonenumber-js-1.10.21.tgz#860312cbec1389e36e28389161025c7817a3ae32" + integrity sha512-/udZhx49av2r2gZR/+xXSrwcR8smX/sDNrVpOFrvW+CA26TfYTVZfwb3MIDvmwAYMLs7pXuJjZX0VxxGpqPhsA== + lie@~3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/lie/-/lie-3.3.0.tgz#dcf82dee545f46074daf200c7c1c5a08e0f40f6a" @@ -14006,7 +14602,7 @@ lodash.upperfirst@^4.3.1: resolved "https://registry.yarnpkg.com/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz#1365edf431480481ef0d1c68957a5ed99d49f7ce" integrity sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg== -lodash@^4.16.3, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.16, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: +lodash@4.17.21, lodash@^4.16.3, lodash@^4.17.11, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.16, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.7.0: version "4.17.21" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -14113,6 +14709,11 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" +lru-cache@^7.14.1: + version "7.18.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-7.18.3.tgz#f793896e0fd0e954a59dfdd82f0773808df6aa89" + integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== + lru-queue@^0.1.0: version "0.1.0" resolved "https://registry.yarnpkg.com/lru-queue/-/lru-queue-0.1.0.tgz#2738bd9f0d3cf4f84490c5736c48699ac632cda3" @@ -14125,6 +14726,11 @@ lru_map@^0.3.3: resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd" integrity sha512-Pn9cox5CsMYngeDbmChANltQl+5pi6XmTrraMSzhPmMBbmgcxmqWry0U3PGapCU1yB4/LqCcom7qhHZiF/jGfQ== +luxon@^3.2.1: + version "3.3.0" + resolved "https://registry.yarnpkg.com/luxon/-/luxon-3.3.0.tgz#d73ab5b5d2b49a461c47cedbc7e73309b4805b48" + integrity sha512-An0UCfG/rSiqtAIiBPO0Y9/zAnHUZxAMiCpTd5h2smgsj7GGmcenvrvww2cqNA8/4A5ZrD1gJpHN2mIHZQF+Mg== + lz-string@^1.4.4, lz-string@^1.5.0: version "1.5.0" resolved "https://registry.yarnpkg.com/lz-string/-/lz-string-1.5.0.tgz#c1ab50f77887b712621201ba9fd4e3a6ed099941" @@ -14158,7 +14764,7 @@ magic-string@^0.30.0: dependencies: "@jridgewell/sourcemap-codec" "^1.4.13" -make-dir@^3.0.0: +make-dir@^3.0.0, make-dir@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-3.1.0.tgz#415e967046b3a7f1d185277d84aa58203726a13f" integrity sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw== @@ -14194,6 +14800,11 @@ map-obj@^4.0.0: resolved "https://registry.yarnpkg.com/map-obj/-/map-obj-4.3.0.tgz#9304f906e93faae70880da102a9f1df0ea8bb05a" integrity sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ== +map-stream@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/map-stream/-/map-stream-0.1.0.tgz#e56aa94c4c8055a16404a0674b78f215f7c8e194" + integrity sha512-CkYQrPYZfWnu/DAmVCpTSX/xHpKZ80eKh2lAkyA6AJTef6bW+6JpbQZN5rofum7da+SyN1bi5ctTm+lTfcCW3g== + markdown-table@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/markdown-table/-/markdown-table-1.1.3.tgz#9fcb69bcfdb8717bfd0398c6ec2d93036ef8de60" @@ -14456,6 +15067,13 @@ minimatch@^5.0.1: dependencies: brace-expansion "^2.0.1" +minimatch@^7.4.1: + version "7.4.2" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-7.4.2.tgz#157e847d79ca671054253b840656720cb733f10f" + integrity sha512-xy4q7wou3vUoC9k1xGTXc+awNdGaGVHtFUaey8tiX4H1QRc04DZ/rmDFwNm2EBsuYEhAZ6SgMmYf3InGY6OauA== + dependencies: + brace-expansion "^2.0.1" + minimist-options@4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/minimist-options/-/minimist-options-4.1.0.tgz#c0655713c53a8a2ebd77ffa247d342c40f010619" @@ -14470,6 +15088,29 @@ minimist@^1.2.0, minimist@^1.2.5, minimist@^1.2.6: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c" integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA== +minio@7.0.30: + version "7.0.30" + resolved "https://registry.yarnpkg.com/minio/-/minio-7.0.30.tgz#3ce9cae7497e13c4c035cacefbb8571de08f0ed7" + integrity sha512-TJiiIhqtf2RSzScOU8IAmKWTb2iMec960tQ0EjYLDgb16FnDmcv0Cr7bHWvYPtS0ueZZ4hBt08TVbal7J2oWJA== + dependencies: + async "^3.1.0" + block-stream2 "^2.0.0" + browser-or-node "^1.3.0" + buffer-crc32 "^0.2.13" + crypto-browserify "^3.12.0" + es6-error "^4.1.1" + fast-xml-parser "^3.17.5" + ipaddr.js "^2.0.1" + json-stream "^1.0.0" + lodash "^4.17.21" + mime-types "^2.1.14" + mkdirp "^0.5.1" + query-string "^7.1.1" + through2 "^3.0.1" + web-encoding "^1.1.5" + xml "^1.0.0" + xml2js "^0.4.15" + minio@^7.0.32: version "7.0.32" resolved "https://registry.yarnpkg.com/minio/-/minio-7.0.32.tgz#fed6a4679c5954d3efc6df47f73f7e7124446e2c" @@ -14508,11 +15149,16 @@ minipass@^3.0.0: dependencies: yallist "^4.0.0" -minipass@^4.0.0: +minipass@^4.0.0, minipass@^4.0.2, minipass@^4.2.4: version "4.2.4" resolved "https://registry.yarnpkg.com/minipass/-/minipass-4.2.4.tgz#7d0d97434b6a19f59c5c3221698b48bbf3b2cd06" integrity sha512-lwycX3cBMTvcejsHITUgYj6Gy6A7Nh4Q6h9NP4sTHY1ccJlC7yKzDmiShEHsJ16Jf1nKGDEaiHxiltsJEvk0nQ== +minipass@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-5.0.0.tgz#3e9788ffb90b694a5d0ec94479a45b5d8738133d" + integrity sha512-3FnjYuehv9k6ovOEbyOswadCDPX1piCfhV8ncmYtHOjuPwylVWsghTLo7rabjC3Rx5xD4HDx8Wm1xnMF7S5qFQ== + minizlib@^1.3.3: version "1.3.3" resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.3.3.tgz#2290de96818a34c29551c8a8d301216bd65a861d" @@ -14540,7 +15186,7 @@ mkdirp@*: resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.5.tgz#78d7eaf15e069ba7b6b47d76dd94cfadf7a4062f" integrity sha512-jbjfql+shJtAPrFoKxHOXip4xS+kul9W3OzfzzrqueWK2QMGon2bFH2opl6W9EagBThjEz+iysyi/swOoVfB/w== -mkdirp@0.5.x, mkdirp@^0.5.1, mkdirp@^0.5.5: +mkdirp@0.5.x, mkdirp@^0.5.1, mkdirp@^0.5.4, mkdirp@^0.5.5: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== @@ -14647,6 +15293,19 @@ ms@2.1.3, ms@^2.0.0, ms@^2.1.1: resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== +multer@1.4.4-lts.1: + version "1.4.4-lts.1" + resolved "https://registry.yarnpkg.com/multer/-/multer-1.4.4-lts.1.tgz#24100f701a4611211cfae94ae16ea39bb314e04d" + integrity sha512-WeSGziVj6+Z2/MwQo3GvqzgR+9Uc+qt8SwHKh3gvNPiISKfsMfG4SvCOFYlxxgkXt7yIV2i1yczehm0EOKIxIg== + dependencies: + append-field "^1.0.0" + busboy "^1.0.0" + concat-stream "^1.5.2" + mkdirp "^0.5.4" + object-assign "^4.1.1" + type-is "^1.6.4" + xtend "^4.0.0" + multiaddr-to-uri@^8.0.0: version "8.0.0" resolved "https://registry.yarnpkg.com/multiaddr-to-uri/-/multiaddr-to-uri-8.0.0.tgz#65efe4b1f9de5f6b681aa42ff36a7c8db7625e58" @@ -14822,7 +15481,7 @@ mustache@^4.2.0: resolved "https://registry.yarnpkg.com/mustache/-/mustache-4.2.0.tgz#e5892324d60a12ec9c2a73359edca52972bf6f64" integrity sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ== -mz@^2.7.0: +mz@^2.4.0, mz@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== @@ -14900,6 +15559,33 @@ neo-async@^2.6.0: resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.2.tgz#b4aafb93e3aeb2d8174ca53cf163ab7d7308305f" integrity sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw== +nestjs-ethers@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/nestjs-ethers/-/nestjs-ethers-2.0.3.tgz#00593f147f92724820585561528fd15ae31d5dbd" + integrity sha512-F/zAX3lfT5CnFNQAwhVqpLIGx3hALyAMTCQayQFc7qAJT+63riNOOqklwPhYGIJAt4VE30naAKFehPzfDDjJ9Q== + dependencies: + "@ethersproject/abstract-signer" "^5.7.0" + "@ethersproject/bignumber" "^5.7.0" + "@ethersproject/bytes" "^5.7.0" + "@ethersproject/contracts" "^5.7.0" + "@ethersproject/json-wallets" "^5.7.0" + "@ethersproject/logger" "^5.7.0" + "@ethersproject/networks" "^5.7.1" + "@ethersproject/providers" "^5.7.2" + "@ethersproject/signing-key" "^5.7.0" + "@ethersproject/wallet" "^5.7.0" + "@ethersproject/web" "^5.7.1" + "@ethersproject/wordlists" "^5.7.0" + +nestjs-minio-client@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/nestjs-minio-client/-/nestjs-minio-client-2.0.0.tgz#791d9baf483f437d26f45addadaead3c81eccc3a" + integrity sha512-TvII1Wzqm+YX9LGjMY4n1GXRy0ngDeHS4lHNA3/8FygaPwjH3gLq1WV1ois+/goBgLjsz1acEkm9KyzalyRHJQ== + dependencies: + minio "7.0.30" + reflect-metadata "^0.1.13" + rxjs "^7.5.6" + next-tick@1, next-tick@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/next-tick/-/next-tick-1.1.0.tgz#1836ee30ad56d67ef281b22bd199f709449b35eb" @@ -14951,6 +15637,11 @@ node-addon-api@^2.0.0: resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-2.0.2.tgz#432cfa82962ce494b132e9d72a15b29f71ff5d32" integrity sha512-Ntyt4AIXyaLIuMHF6IOoTakB3K+RWxwtsHNRxllEoA6vPwP9o4866g6YWDLUdnucilZhmkxiHwHr11gAENw+QA== +node-addon-api@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-5.1.0.tgz#49da1ca055e109a23d537e9de43c09cca21eb762" + integrity sha512-eh0GgfEkpnoWDq+VY8OyvYhFEzBk6jIYbRKdIlyTiAXIVJ8PyBaKb0rp7oDtoddbdoHWhq8wwr+XZ81F1rpNdA== + node-cache@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/node-cache/-/node-cache-5.1.2.tgz#f264dc2ccad0a780e76253a694e9fd0ed19c398d" @@ -14958,6 +15649,11 @@ node-cache@^5.1.2: dependencies: clone "2.x" +node-cleanup@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/node-cleanup/-/node-cleanup-2.1.2.tgz#7ac19abd297e09a7f72a71545d951b517e4dde2c" + integrity sha512-qN8v/s2PAJwGUtr1/hYTpNKlD6Y9rc4p8KSmJXyGdYGZsDGKXrGThikLFP9OCHFeLeEpQzPwiAtdIvBLqm//Hw== + node-emoji@^1.10.0: version "1.11.0" resolved "https://registry.yarnpkg.com/node-emoji/-/node-emoji-1.11.0.tgz#69a0150e6946e2f115e9d7ea4df7971e2628301c" @@ -15045,6 +15741,13 @@ nopt@3.x: dependencies: abbrev "1" +nopt@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-5.0.0.tgz#530942bb58a512fccafe53fe210f13a25355dc88" + integrity sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ== + dependencies: + abbrev "1" + normalize-package-data@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz#e66db1838b200c1dfc233225d12cb36520e234a8" @@ -15096,6 +15799,16 @@ npm-run-path@^5.1.0: dependencies: path-key "^4.0.0" +npmlog@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-5.0.1.tgz#f06678e80e29419ad67ab964e0fa69959c1eb8b0" + integrity sha512-AqZtDUWOMKs1G/8lwylVjrdYgqA4d9nu8hc+0gzRxlDb1I10+FHBGMXs6aiQHFdCUUlqH99MUMuLfzWDNDtfxw== + dependencies: + are-we-there-yet "^2.0.0" + console-control-strings "^1.1.0" + gauge "^3.0.0" + set-blocking "^2.0.0" + nth-check@^2.0.1: version "2.1.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" @@ -15131,6 +15844,11 @@ oauth-sign@~0.9.0: resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== +oauth@0.9.x: + version "0.9.15" + resolved "https://registry.yarnpkg.com/oauth/-/oauth-0.9.15.tgz#bd1fefaf686c96b75475aed5196412ff60cfb9c1" + integrity sha512-a5ERWK1kh38ExDEfoO6qUHJb32rd7aYmPHuyCu3Fta/cnICvYmgd2uhuKXvPD+PXB+gCEYYEaQdIRAjCOwAKNA== + object-assign@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-2.1.1.tgz#43c36e5d569ff8e4816c4efa8be02d26967c18aa" @@ -15463,6 +16181,11 @@ p-try@^2.0.0: resolved "https://registry.yarnpkg.com/p-try/-/p-try-2.2.0.tgz#cb2868540e313d61de58fafbe35ce9004d5540e6" integrity sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ== +packet-reader@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/packet-reader/-/packet-reader-1.0.0.tgz#9238e5480dedabacfe1fe3f2771063f164157d74" + integrity sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ== + pako@~1.0.2, pako@~1.0.5: version "1.0.11" resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.11.tgz#6c9599d340d54dfd3946380252a35705a6b992bf" @@ -15511,6 +16234,13 @@ parse-json@^5.0.0, parse-json@^5.2.0: json-parse-even-better-errors "^2.3.0" lines-and-columns "^1.1.6" +parse5-htmlparser2-tree-adapter@^6.0.0: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz#2cdf9ad823321140370d4dbf5d3e92c7c8ddc6e6" + integrity sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA== + dependencies: + parse5 "^6.0.1" + parse5-htmlparser2-tree-adapter@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz#23c2cc233bcf09bb7beba8b8a69d46b08c62c2f1" @@ -15519,11 +16249,16 @@ parse5-htmlparser2-tree-adapter@^7.0.0: domhandler "^5.0.2" parse5 "^7.0.0" -parse5@6.0.1: +parse5@6.0.1, parse5@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== +parse5@^5.1.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-5.1.1.tgz#f68e4e5ba1852ac2cadc00f4555fff6c2abb6178" + integrity sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug== + parse5@^7.0.0, parse5@^7.1.1: version "7.1.2" resolved "https://registry.yarnpkg.com/parse5/-/parse5-7.1.2.tgz#0736bebbfd77793823240a23b7fc5e010b7f8e32" @@ -15536,6 +16271,77 @@ parseurl@~1.3.3: resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4" integrity sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ== +passport-facebook@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/passport-facebook/-/passport-facebook-3.0.0.tgz#b16f7314128be55d020a2b75f574c194bd6d9805" + integrity sha512-K/qNzuFsFISYAyC1Nma4qgY/12V3RSLFdFVsPKXiKZt434wOvthFW1p7zKa1iQihQMRhaWorVE1o3Vi1o+ZgeQ== + dependencies: + passport-oauth2 "1.x.x" + +passport-google-oauth1@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-google-oauth1/-/passport-google-oauth1-1.0.0.tgz#af74a803df51ec646f66a44d82282be6f108e0cc" + integrity sha512-qpCEhuflJgYrdg5zZIpAq/K3gTqa1CtHjbubsEsidIdpBPLkEVq6tB1I8kBNcH89RdSiYbnKpCBXAZXX/dtx1Q== + dependencies: + passport-oauth1 "1.x.x" + +passport-google-oauth20@2.x.x: + version "2.0.0" + resolved "https://registry.yarnpkg.com/passport-google-oauth20/-/passport-google-oauth20-2.0.0.tgz#0d241b2d21ebd3dc7f2b60669ec4d587e3a674ef" + integrity sha512-KSk6IJ15RoxuGq7D1UKK/8qKhNfzbLeLrG3gkLZ7p4A6DBCcv7xpyQwuXtWdpyR0+E0mwkpjY1VfPOhxQrKzdQ== + dependencies: + passport-oauth2 "1.x.x" + +passport-google-oauth@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/passport-google-oauth/-/passport-google-oauth-2.0.0.tgz#f6eb4bc96dd6c16ec0ecfdf4e05ec48ca54d4dae" + integrity sha512-JKxZpBx6wBQXX1/a1s7VmdBgwOugohH+IxCy84aPTZNq/iIPX6u7Mqov1zY7MKRz3niFPol0KJz8zPLBoHKtYA== + dependencies: + passport-google-oauth1 "1.x.x" + passport-google-oauth20 "2.x.x" + +passport-jwt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/passport-jwt/-/passport-jwt-4.0.1.tgz#c443795eff322c38d173faa0a3c481479646ec3d" + integrity sha512-UCKMDYhNuGOBE9/9Ycuoyh7vP6jpeTp/+sfMJl7nLff/t6dps+iaeE0hhNkKN8/HZHcJ7lCdOyDxHdDoxoSvdQ== + dependencies: + jsonwebtoken "^9.0.0" + passport-strategy "^1.0.0" + +passport-oauth1@1.x.x: + version "1.3.0" + resolved "https://registry.yarnpkg.com/passport-oauth1/-/passport-oauth1-1.3.0.tgz#5d57f1415c8e28e46b461a12ec1b492934f7c354" + integrity sha512-8T/nX4gwKTw0PjxP1xfD0QhrydQNakzeOpZ6M5Uqdgz9/a/Ag62RmJxnZQ4LkbdXGrRehQHIAHNAu11rCP46Sw== + dependencies: + oauth "0.9.x" + passport-strategy "1.x.x" + utils-merge "1.x.x" + +passport-oauth2@1.x.x: + version "1.7.0" + resolved "https://registry.yarnpkg.com/passport-oauth2/-/passport-oauth2-1.7.0.tgz#5c4766c8531ac45ffe9ec2c09de9809e2c841fc4" + integrity sha512-j2gf34szdTF2Onw3+76alNnaAExlUmHvkc7cL+cmaS5NzHzDP/BvFHJruueQ9XAeNOdpI+CH+PWid8RA7KCwAQ== + dependencies: + base64url "3.x.x" + oauth "0.9.x" + passport-strategy "1.x.x" + uid2 "0.0.x" + utils-merge "1.x.x" + +passport-strategy@1.x.x, passport-strategy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/passport-strategy/-/passport-strategy-1.0.0.tgz#b5539aa8fc225a3d1ad179476ddf236b440f52e4" + integrity sha512-CB97UUvDKJde2V0KDWWB3lyf6PC3FaZP7YxZ2G8OAtn9p4HI9j9JLP9qjOGZFvyl8uwNT8qM+hGnz/n16NI7oA== + +passport@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/passport/-/passport-0.6.0.tgz#e869579fab465b5c0b291e841e6cc95c005fac9d" + integrity sha512-0fe+p3ZnrWRW74fe8+SvCyf4a3Pb2/h7gFkQ8yTJpAO50gDzlfjZUZTO1k5Eg9kUct22OxHLqDZoKUWRHOh9ug== + dependencies: + passport-strategy "1.x.x" + pause "0.0.1" + utils-merge "^1.0.1" + path-browserify@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-1.0.1.tgz#d98454a9c3753d5790860f16f68867b9e46be1fd" @@ -15576,6 +16382,14 @@ path-parse@^1.0.6, path-parse@^1.0.7: resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== +path-scurry@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/path-scurry/-/path-scurry-1.6.1.tgz#dab45f7bb1d3f45a0e271ab258999f4ab7e23132" + integrity sha512-OW+5s+7cw6253Q4E+8qQ/u1fVvcJQCJo/VFD8pje+dbJCF1n5ZRMV2AEHbGp+5Q7jxQIYJxkHopnj6nzdGeZLA== + dependencies: + lru-cache "^7.14.1" + minipass "^4.0.2" + path-starts-with@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/path-starts-with/-/path-starts-with-2.0.0.tgz#ffd6d51926cd497022b44d392196033d5451892f" @@ -15591,6 +16405,11 @@ path-to-regexp@2.2.1: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-2.2.1.tgz#90b617025a16381a879bc82a38d4e8bdeb2bcf45" integrity sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ== +path-to-regexp@3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-3.2.0.tgz#fa7877ecbc495c601907562222453c43cc204a5f" + integrity sha512-jczvQbCUS7XmS7o+y1aEO9OBVFeZBQ1MDSEqmO7xSoPgOPoowY/SxLpZ6Vh97/8qHZOteiCKb7gkG9gA2ZUxJA== + path-to-regexp@^1.7.0: version "1.8.0" resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-1.8.0.tgz#887b3ba9d84393e87a0a0b9f4cb756198b53548a" @@ -15613,6 +16432,18 @@ pathval@^1.1.1: resolved "https://registry.yarnpkg.com/pathval/-/pathval-1.1.1.tgz#8534e77a77ce7ac5a2512ea21e0fdb8fcf6c3d8d" integrity sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ== +pause-stream@0.0.11: + version "0.0.11" + resolved "https://registry.yarnpkg.com/pause-stream/-/pause-stream-0.0.11.tgz#fe5a34b0cbce12b5aa6a2b403ee2e73b602f1445" + integrity sha512-e3FBlXLmN/D1S+zHzanP4E/4Z60oFAa3O051qt1pxa7DEJWKAyil6upYVXCWadEnuoqa4Pkc9oUx9zsxYeRv8A== + dependencies: + through "~2.3" + +pause@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/pause/-/pause-0.0.1.tgz#1d408b3fdb76923b9543d96fb4c9dfd535d9cb5d" + integrity sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg== + pbkdf2@^3.0.17, pbkdf2@^3.0.3: version "3.1.2" resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.1.2.tgz#dd822aa0887580e52f1a039dc3eda108efae3075" @@ -15656,6 +16487,57 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow== +pg-connection-string@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34" + integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ== + +pg-int8@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" + integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== + +pg-pool@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.6.0.tgz#3190df3e4747a0d23e5e9e8045bcd99bda0a712e" + integrity sha512-clFRf2ksqd+F497kWFyM21tMjeikn60oGDmqMT8UBrynEwVEX/5R5xd2sdvdo1cZCFlguORNpVuqxIj+aK4cfQ== + +pg-protocol@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.6.0.tgz#4c91613c0315349363af2084608db843502f8833" + integrity sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q== + +pg-types@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" + integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== + dependencies: + pg-int8 "1.0.1" + postgres-array "~2.0.0" + postgres-bytea "~1.0.0" + postgres-date "~1.0.4" + postgres-interval "^1.1.0" + +pg@^8.10.0: + version "8.10.0" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.10.0.tgz#5b8379c9b4a36451d110fc8cd98fc325fe62ad24" + integrity sha512-ke7o7qSTMb47iwzOSaZMfeR7xToFdkE71ifIipOAAaLIM0DYzfOAXlgFFmYUIE2BcJtvnVlGCID84ZzCegE8CQ== + dependencies: + buffer-writer "2.0.0" + packet-reader "1.0.0" + pg-connection-string "^2.5.0" + pg-pool "^3.6.0" + pg-protocol "^1.6.0" + pg-types "^2.1.0" + pgpass "1.x" + +pgpass@1.x: + version "1.0.5" + resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" + integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== + dependencies: + split2 "^4.1.0" + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -15852,6 +16734,28 @@ postcss@^8.4.21: picocolors "^1.0.0" source-map-js "^1.0.2" +postgres-array@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/postgres-array/-/postgres-array-2.0.0.tgz#48f8fce054fbc69671999329b8834b772652d82e" + integrity sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA== + +postgres-bytea@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/postgres-bytea/-/postgres-bytea-1.0.0.tgz#027b533c0aa890e26d172d47cf9ccecc521acd35" + integrity sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w== + +postgres-date@~1.0.4: + version "1.0.7" + resolved "https://registry.yarnpkg.com/postgres-date/-/postgres-date-1.0.7.tgz#51bc086006005e5061c591cee727f2531bf641a8" + integrity sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q== + +postgres-interval@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/postgres-interval/-/postgres-interval-1.2.0.tgz#b460c82cb1587507788819a06aa0fffdb3544695" + integrity sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ== + dependencies: + xtend "^4.0.0" + preact@^10.12.0, preact@^10.5.9: version "10.13.1" resolved "https://registry.yarnpkg.com/preact/-/preact-10.13.1.tgz#d220bd8771b8fa197680d4917f3cefc5eed88720" @@ -16043,6 +16947,13 @@ proxy-from-env@^1.1.0: resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz#e102f16ca355424865755d2c9e8ea4f24d58c3e2" integrity sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg== +ps-tree@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ps-tree/-/ps-tree-1.2.0.tgz#5e7425b89508736cdd4f2224d028f7bb3f722ebd" + integrity sha512-0VnamPPYHl4uaU/nSFeZZpR21QAWRz+sRv4iW9+v/GS/J5U5iZB5BNN6J0RMoOvdx2gWM2+ZFMIm58q24e4UYA== + dependencies: + event-stream "=3.3.4" + psl@^1.1.28, psl@^1.1.33: version "1.9.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.9.0.tgz#d0df2a137f00794565fcaf3b2c00cd09f8d5a5a7" @@ -16245,6 +17156,11 @@ rabin-wasm@^0.1.4: node-fetch "^2.6.1" readable-stream "^3.6.0" +random-bytes@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/random-bytes/-/random-bytes-1.0.0.tgz#4f68a1dc0ae58bd3fb95848c30324db75d64360b" + integrity sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ== + randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5, randombytes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.1.0.tgz#df6f84372f0270dc65cdf6291349ab7a473d4f2a" @@ -16587,6 +17503,11 @@ redux@^4.2.0: dependencies: "@babel/runtime" "^7.9.2" +reflect-metadata@^0.1.13: + version "0.1.13" + resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08" + integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg== + regenerate-unicode-properties@^10.1.0: version "10.1.0" resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-10.1.0.tgz#7c3192cab6dd24e21cb4461e5ddd7dd24fa8374c" @@ -16620,7 +17541,7 @@ regexp.prototype.flags@^1.4.3: define-properties "^1.1.3" functions-have-names "^1.2.2" -regexpp@^3.1.0, regexpp@^3.2.0: +regexpp@^3.0.0, regexpp@^3.1.0, regexpp@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" integrity sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg== @@ -16799,7 +17720,7 @@ resolve@1.17.0: dependencies: path-parse "^1.0.6" -resolve@^1.1.6, resolve@^1.10.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.1: +resolve@^1.1.6, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.22.1: version "1.22.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177" integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw== @@ -16890,6 +17811,13 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" +rimraf@^4.3.1: + version "4.3.1" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-4.3.1.tgz#ccb3525e39100478acb334fae6d23029b87912ea" + integrity sha512-GfHJHBzFQra23IxDzIdBqhOWfbtdgS1/dCHrDy+yvhpoJY5TdwdT28oWaHWfRpKFDLd3GZnGTx6Mlt4+anbsxQ== + dependencies: + glob "^9.2.0" + ripemd160@^2.0.0, ripemd160@^2.0.1: version "2.0.2" resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" @@ -16987,7 +17915,7 @@ rxjs@^6.6.3: dependencies: tslib "^1.9.0" -rxjs@^7.0.0, rxjs@^7.8.0: +rxjs@^7.0.0, rxjs@^7.5.6, rxjs@^7.8.0: version "7.8.0" resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-7.8.0.tgz#90a938862a82888ff4c7359811a595e14e1e09a4" integrity sha512-F2+gxDshqmIub1KdvZkaEfGDwLNpPvk9Fs6LD/MyQxNgMds/WH9OdDDXOmxUZpME+iSK3rQCctkL0DYyytUqMg== @@ -17155,7 +18083,7 @@ semver@7.x, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8: dependencies: lru-cache "^6.0.0" -semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: +semver@^6.0.0, semver@^6.1.0, semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== @@ -17326,7 +18254,7 @@ siginfo@^2.0.0: resolved "https://registry.yarnpkg.com/siginfo/-/siginfo-2.0.0.tgz#32e76c70b79724e3bb567cb9d543eb858ccfaf30" integrity sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g== -signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.7.tgz#a9a1767f8af84155114eaabd73f99273c8f59ad9" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -17595,11 +18523,18 @@ split2@^3.1.0: dependencies: readable-stream "^3.0.0" -split2@^4.0.0: +split2@^4.0.0, split2@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/split2/-/split2-4.1.0.tgz#101907a24370f85bb782f08adaabe4e281ecf809" integrity sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ== +split@0.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/split/-/split-0.3.3.tgz#cd0eea5e63a211dfff7eb0f091c4133e2d0dd28f" + integrity sha512-wD2AeVmxXRBoX44wAycgjVpMhvbwdI2aZjCkvfNcH1YqHQvJVa1duWc73OyVGJUc05fhFaTZeQ/PYsrmyH0JVA== + dependencies: + through "2" + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" @@ -17684,6 +18619,13 @@ stream-browserify@^3.0.0: inherits "~2.0.4" readable-stream "^3.5.0" +stream-combiner@~0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/stream-combiner/-/stream-combiner-0.0.4.tgz#4d5e433c185261dde623ca3f44c586bcf5c4ad14" + integrity sha512-rT00SPnTVyRsaSz5zgSPma/aHSOic5U1prhYdRy5HS2kTZviFpmDgzilbtsJsxiroqACmayynDN/9VzIbX5DOw== + dependencies: + duplexer "~0.1.1" + stream-http@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-3.2.0.tgz#1872dfcf24cb15752677e40e5c3f9cc1926028b5" @@ -17762,15 +18704,7 @@ string-natural-compare@^3.0.1: resolved "https://registry.yarnpkg.com/string-natural-compare/-/string-natural-compare-3.0.1.tgz#7a42d58474454963759e8e8b7ae63d71c1e7fdf4" integrity sha512-n3sPwynL1nwKi3WJ6AIsClwBMa0zTi54fn2oLU6ndfTSIO05xaznjSf15PcBZU6FNWbmN5Q6cxT4V5hGvB4taw== -string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -17779,6 +18713,14 @@ string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.3: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + string-width@^5.0.0, string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" @@ -17982,6 +18924,11 @@ supports-preserve-symlinks-flag@^1.0.0: resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== +swagger-ui-dist@4.15.5: + version "4.15.5" + resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-4.15.5.tgz#cda226a79db2a9192579cc1f37ec839398a62638" + integrity sha512-V3eIa28lwB6gg7/wfNvAbjwJYmDXy1Jo1POjyTzlB6wPcHiGlRxq39TSjYGVjQrUSAzpv+a7nzp7mDxgNy57xA== + swarm-js@^0.1.40: version "0.1.42" resolved "https://registry.yarnpkg.com/swarm-js/-/swarm-js-0.1.42.tgz#497995c62df6696f6e22372f457120e43e727979" @@ -18123,6 +19070,18 @@ tar@^6.1.0: mkdirp "^1.0.3" yallist "^4.0.0" +tar@^6.1.11: + version "6.1.15" + resolved "https://registry.yarnpkg.com/tar/-/tar-6.1.15.tgz#c9738b0b98845a3b344d334b8fa3041aaba53a69" + integrity sha512-/zKt9UyngnxIT/EAGYuxaMYgOIJiP81ab9ZfkILq4oNLPFX50qyYmu7jRj9qeXoxmJHjGlbH0+cm2uy1WCs10A== + dependencies: + chownr "^2.0.0" + fs-minipass "^2.0.0" + minipass "^5.0.0" + minizlib "^2.1.1" + mkdirp "^1.0.3" + yallist "^4.0.0" + tenderly@^0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/tenderly/-/tenderly-0.4.0.tgz#681e2efdec48f4617117ddfce9612fe1b57fdf78" @@ -18233,7 +19192,7 @@ through2@^3.0.0, through2@^3.0.1: inherits "^2.0.4" readable-stream "2 || 3" -"through@>=2.2.7 <3", through@^2.3.8: +through@2, "through@>=2.2.7 <3", through@^2.3.8, through@~2.3, through@~2.3.1: version "2.3.8" resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" integrity sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg== @@ -18271,7 +19230,7 @@ timers-ext@^0.1.7: es5-ext "~0.10.46" next-tick "1" -tiny-glob@^0.2.9: +tiny-glob@^0.2.6, tiny-glob@^0.2.9: version "0.2.9" resolved "https://registry.yarnpkg.com/tiny-glob/-/tiny-glob-0.2.9.tgz#2212d441ac17928033b110f8b3640683129d31e2" integrity sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg== @@ -18489,7 +19448,17 @@ ts-node@^10.9.1: v8-compile-cache-lib "^3.0.1" yn "3.1.1" -tsconfig-paths@^3.14.1: +tsc-watch@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/tsc-watch/-/tsc-watch-6.0.0.tgz#474b661b8d6a226c0921a3b6048d7a91f61d888a" + integrity sha512-zgpju+/z5z29/kK5V28Nz16CMkX2voFOUxkTlCim/R25hxzbyUqu2NfTnmJBQfESBSPbEQUGqDdB9A8opAcB4A== + dependencies: + cross-spawn "^7.0.3" + node-cleanup "^2.1.2" + ps-tree "^1.2.0" + string-argv "^0.3.1" + +tsconfig-paths@^3.14.1, tsconfig-paths@^3.9.0: version "3.14.2" resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz#6e32f1f79412decd261f92d633a9dc1cfa99f088" integrity sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g== @@ -18504,11 +19473,16 @@ tslib@1.14.1, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.1.0, tslib@^2.3.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.4.1, tslib@^2.5.0: +tslib@2.5.0, tslib@^2.0.0, tslib@^2.1.0, tslib@^2.3.1, tslib@^2.4.0, tslib@^2.4.1, tslib@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.0.tgz#42bfed86f5787aeb41d031866c8f402429e0fddf" integrity sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg== +tslib@^2.3.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.2.tgz#1b6f07185c881557b0ffa84b111a0106989e8338" + integrity sha512-5svOrSA2w3iGFDs1HibEVBGbDrAY82bFQ3HZ3ixB+88nsbsWQoKqDRb5UBYAUPEzbBn6dAp5gRNXglySbx1MlA== + tslog@^4.3.1, tslog@^4.4.0: version "4.8.2" resolved "https://registry.yarnpkg.com/tslog/-/tslog-4.8.2.tgz#dbb0c96249e387e8a711ae6e077330ba1ef102c9" @@ -18618,7 +19592,7 @@ type-fest@^2.13.0: resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-2.19.0.tgz#88068015bb33036a598b952e55e9311a60fd3a9b" integrity sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA== -type-is@~1.6.18: +type-is@^1.6.4, type-is@~1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -18673,6 +19647,34 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA== +typeorm-naming-strategies@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/typeorm-naming-strategies/-/typeorm-naming-strategies-4.1.0.tgz#1ec6eb296c8d7b69bb06764d5b9083ff80e814a9" + integrity sha512-vPekJXzZOTZrdDvTl1YoM+w+sUIfQHG4kZTpbFYoTsufyv9NIBRe4Q+PdzhEAFA2std3D9LZHEb1EjE9zhRpiQ== + +typeorm@0.2.43: + version "0.2.43" + resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.43.tgz#110d629ed5d0b014c735f0213f06b34abb32d298" + integrity sha512-j4SU8I0PsMWtF64s/9tOJmlexzfDsvXhTjSE2GXdSseUN8TYyfbCm/fJnC6lx3uHgBJL4z9bE8U/7qyC/FVmNw== + dependencies: + "@sqltools/formatter" "^1.2.2" + app-root-path "^3.0.0" + buffer "^6.0.3" + chalk "^4.1.0" + cli-highlight "^2.1.11" + debug "^4.3.1" + dotenv "^8.2.0" + glob "^7.1.6" + js-yaml "^4.0.0" + mkdirp "^1.0.4" + reflect-metadata "^0.1.13" + sha.js "^2.4.11" + tslib "^2.1.0" + uuid "^8.3.2" + xml2js "^0.4.23" + yargs "^17.0.1" + zen-observable-ts "^1.0.0" + typescript@^4.5.5, typescript@^4.9.3, typescript@^4.9.5: version "4.9.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a" @@ -18698,6 +19700,25 @@ uglify-js@^3.1.4: resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.17.4.tgz#61678cf5fa3f5b7eb789bb345df29afb8257c22c" integrity sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g== +uid-safe@~2.1.5: + version "2.1.5" + resolved "https://registry.yarnpkg.com/uid-safe/-/uid-safe-2.1.5.tgz#2b3d5c7240e8fc2e58f8aa269e5ee49c0857bd3a" + integrity sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA== + dependencies: + random-bytes "~1.0.0" + +uid2@0.0.x: + version "0.0.4" + resolved "https://registry.yarnpkg.com/uid2/-/uid2-0.0.4.tgz#033f3b1d5d32505f5ce5f888b9f3b667123c0a44" + integrity sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA== + +uid@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/uid/-/uid-2.0.1.tgz#a3f57c962828ea65256cd622fc363028cdf4526b" + integrity sha512-PF+1AnZgycpAIEmNtjxGBVmKbZAQguaa4pBUq6KNaGEcpzZ2klCNZLM34tsjp76maN00TttiiUf6zkIBpJQm2A== + dependencies: + "@lukeed/csprng" "^1.0.0" + uint8arrays@^3.0.0, uint8arrays@^3.1.0: version "3.1.1" resolved "https://registry.yarnpkg.com/uint8arrays/-/uint8arrays-3.1.1.tgz#2d8762acce159ccd9936057572dade9459f65ae0" @@ -18892,7 +19913,7 @@ util@^0.12.0, util@^0.12.3, util@^0.12.4, util@^0.12.5: is-typed-array "^1.1.3" which-typed-array "^1.1.2" -utils-merge@1.0.1: +utils-merge@1.0.1, utils-merge@1.x.x, utils-merge@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== @@ -18907,6 +19928,16 @@ uuid@8.0.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.0.0.tgz#bc6ccf91b5ff0ac07bbcdbf1c7c4e150db4dbb6c" integrity sha512-jOXGuXZAWdsTH7eZLtyXMqUb9EcWMGZNbL9YcGBJl4MH4nrxHmZJhEHvyLFrkxo+28uLb/NYRcStH48fnD0Vzw== +uuid@8.3.2, uuid@^8.3.2: + version "8.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" + integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== + +uuid@9.0.0, uuid@^9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" + integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== + uuid@^3.3.2: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" @@ -18917,16 +19948,6 @@ uuid@^7.0.3: resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== -uuid@^8.3.2: - version "8.3.2" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" - integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== - -uuid@^9.0.0: - version "9.0.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5" - integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg== - v8-compile-cache-lib@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz#6336e8d71965cb3d35a1bbb7868445a7c05264bf" @@ -18963,6 +19984,11 @@ validate-npm-package-license@^3.0.1: spdx-correct "^3.0.0" spdx-expression-parse "^3.0.0" +validator@^13.7.0: + version "13.9.0" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.9.0.tgz#33e7b85b604f3bbce9bb1a05d5c3e22e1c2ff855" + integrity sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA== + valtio@1.10.3: version "1.10.3" resolved "https://registry.yarnpkg.com/valtio/-/valtio-1.10.3.tgz#273eda9ba6459869798b4f58c84514e18fb80ed8" @@ -19743,6 +20769,20 @@ why-is-node-running@^2.2.2: siginfo "^2.0.0" stackback "0.0.2" +wide-align@^1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" + integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg== + dependencies: + string-width "^1.0.2 || 2 || 3 || 4" + +widest-line@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-3.1.0.tgz#8292333bbf66cb45ff0de1603b136b7ae1496eca" + integrity sha512-NsmoXalsWVDMGupxZ5R08ka9flZjjiLvHVAWYOKtiKM8ujtZWr9cRffak+uSE48+Ob8ObalXpwyeUiyDD6QFgg== + dependencies: + string-width "^4.0.0" + widest-line@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/widest-line/-/widest-line-4.0.1.tgz#a0fc673aaba1ea6f0a0d35b3c2795c9a9cc2ebf2" @@ -19936,7 +20976,7 @@ xml2js@0.4.19: sax ">=0.6.0" xmlbuilder "~9.0.1" -xml2js@^0.4.15: +xml2js@^0.4.15, xml2js@^0.4.23: version "0.4.23" resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.4.23.tgz#a0c69516752421eb2ac758ee4d4ccf58843eac66" integrity sha512-ySPiMjM0+pLDftHgXY4By0uswI3SPKLDw/i3UXbnO8M/p28zqexCUoPmQFrYD+/1BzhGJSs2i1ERWKJAtiLrug== @@ -20049,7 +21089,7 @@ yargs-unparser@2.0.0: flat "^5.0.2" is-plain-obj "^2.1.0" -yargs@16.2.0, yargs@^16.2.0: +yargs@16.2.0, yargs@^16.0.0, yargs@^16.2.0: version "16.2.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== @@ -20079,7 +21119,7 @@ yargs@^15.3.1: y18n "^4.0.0" yargs-parser "^18.1.2" -yargs@^17.3.1: +yargs@^17.0.1, yargs@^17.3.1: version "17.7.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.1.tgz#34a77645201d1a8fc5213ace787c220eabbd0967" integrity sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw== @@ -20107,6 +21147,14 @@ yocto-queue@^1.0.0: resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-1.0.0.tgz#7f816433fb2cbc511ec8bf7d263c3b58a1a3c251" integrity sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g== +zen-observable-ts@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.1.0.tgz#2d1aa9d79b87058e9b75698b92791c1838551f83" + integrity sha512-1h4zlLSqI2cRLPJUHJFL8bCWHhkpuXkF+dbGkRaWjgDIG26DmzyshUMrdV/rL3UnR+mhaX4fRq8LPouq0MYYIA== + dependencies: + "@types/zen-observable" "0.8.3" + zen-observable "0.8.15" + zen-observable-ts@^1.2.5: version "1.2.5" resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-1.2.5.tgz#6c6d9ea3d3a842812c6e9519209365a122ba8b58" @@ -20130,3 +21178,8 @@ zustand@^4.3.1: integrity sha512-6J5zDxjxLE+yukC2XZWf/IyWVKnXT9b9HUv09VJ/bwGCpKNcaTqp7Ws28Xr8jnbvnZcdRaidztAPsXFBIqufiw== dependencies: use-sync-external-store "1.2.0" + +zxcvbn@^4.4.2: + version "4.4.2" + resolved "https://registry.yarnpkg.com/zxcvbn/-/zxcvbn-4.4.2.tgz#28ec17cf09743edcab056ddd8b1b06262cc73c30" + integrity sha512-Bq0B+ixT/DMyG8kgX2xWcI5jUvCwqrMxSFam7m0lAf78nf04hv6lNCsyLYdyYTrCVMqNDY/206K7eExYCeSyUQ==