diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index ee710c57a..55e28db4b 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -72,7 +72,7 @@ jobs: ########################################################################## - name: Backend | Build `production` image run: | - docker build --target production -t "gradido/backend:latest" -t "gradido/backend:production" -t "gradido/backend:${VERSION}" -t "gradido/backend:${BUILD_VERSION}" backend/ + docker build -f ./backend/Dockerfile --target production -t "gradido/backend:latest" -t "gradido/backend:production" -t "gradido/backend:${VERSION}" -t "gradido/backend:${BUILD_VERSION}" . docker save "gradido/backend" > /tmp/backend.tar - name: Upload Artifact uses: actions/upload-artifact@v2 diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 087602c21..209e39af8 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -47,7 +47,7 @@ jobs: ########################################################################## - name: Backend | Build `test` image run: | - docker build --target test -t "gradido/backend:test" backend/ + docker build -f ./backend/Dockerfile --target test -t "gradido/backend:test" backend/ docker save "gradido/backend:test" > /tmp/backend.tar - name: Upload Artifact uses: actions/upload-artifact@v2 @@ -147,7 +147,7 @@ jobs: ########################################################################## - name: mariadb | Build `test` image run: | - docker build --target mariadb_server_test -t "gradido/mariadb:test" -f ./mariadb/Dockerfile ./ + docker build --target mariadb_server -t "gradido/mariadb:test" -f ./mariadb/Dockerfile ./ docker save "gradido/mariadb:test" > /tmp/mariadb.tar - name: Upload Artifact uses: actions/upload-artifact@v2 @@ -344,7 +344,7 @@ jobs: report_name: Coverage Frontend type: lcov result_path: ./coverage/lcov.info - min_coverage: 82 + min_coverage: 83 token: ${{ github.token }} ############################################################################## @@ -416,10 +416,16 @@ jobs: --health-timeout=3s --health-retries=4 steps: - - name: Debug service - run: echo "$(docker ps)" - - name: Debug container choosing script - run: echo "$(docker container ls | grep mariadb | awk '{ print $1 }')" + # - name: Debug service + # run: echo "$(docker ps)" + #- name: Debug container choosing script + # run: echo "$(docker container ls | grep mariadb | awk '{ print $1 }')" + - name: get mariadb container id + run: echo "::set-output name=id::$(docker container ls | grep mariadb | awk '{ print $1 }')" + id: mariadb_container + - name: get automatic created network + run: echo "::set-output name=id::$(docker network ls | grep github_network | awk '{ print $1 }')" + id: network ########################################################################## # CHECKOUT CODE ########################################################## ########################################################################## @@ -427,6 +433,11 @@ jobs: uses: actions/checkout@v2 with: submodules: true + # Database migration + - name: Start database migration + run: | + docker build --target production_up -t "gradido/database:production_up" database/ + docker run --network ${{ steps.network.outputs.id }} --name=database --env NODE_ENV=production --env DB_HOST=mariadb --env DB_DATABASE=gradido_community_test -d gradido/database:production_up ########################################################################## # Build Login-Server Test Docker image ################################### ########################################################################## diff --git a/.gitignore b/.gitignore index caed320af..c09811443 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,6 @@ /node_modules/* .vscode messages.pot -.skeema nbproject .metadata /.env diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..a6dc06683 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "streetsidesoftware.code-spell-checker", + "dbaeumer.vscode-eslint", + "esbenp.prettier-vscode" + ] +} \ No newline at end of file diff --git a/backend/Dockerfile b/backend/Dockerfile index a65ddaa92..035841c17 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -42,6 +42,8 @@ EXPOSE ${PORT} RUN mkdir -p ${DOCKER_WORKDIR} WORKDIR ${DOCKER_WORKDIR} +RUN mkdir -p /database + ################################################################################## # DEVELOPMENT (Connected to the local environment, to reload on demand) ########## ################################################################################## @@ -51,22 +53,32 @@ FROM base as development # local filesystem which will need a rebuild anyway # Run command -# (for development we need to execute npm install since the +# (for development we need to execute yarn install since the # node_modules are on another volume and need updating) -CMD /bin/sh -c "yarn install && yarn run dev" +CMD /bin/sh -c "cd /database && yarn install && yarn build && cd /app && yarn install && yarn run dev" ################################################################################## # BUILD (Does contain all files and is therefore bloated) ######################## ################################################################################## FROM base as build -# Copy everything -COPY . . -# npm install +# Copy everything from backend +COPY ./backend/ ./ +# Copy everything from database +COPY ./database/ ../database/ + +# yarn install backend RUN yarn install --production=false --frozen-lockfile --non-interactive -# npm build + +# yarn install database +RUN cd ../database && yarn install --production=false --frozen-lockfile --non-interactive + +# yarn build RUN yarn run build +# yarn build database +RUN cd ../database && yarn run build + ################################################################################## # TEST ########################################################################### ################################################################################## @@ -82,8 +94,10 @@ FROM base as production # Copy "binary"-files from build image COPY --from=build ${DOCKER_WORKDIR}/build ./build +COPY --from=build ${DOCKER_WORKDIR}/../database/build ../database/build # We also copy the node_modules express and serve-static for the run script -# COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules +COPY --from=build ${DOCKER_WORKDIR}/node_modules ./node_modules +COPY --from=build ${DOCKER_WORKDIR}/../database/node_modules ../database/node_modules # Copy static files # COPY --from=build ${DOCKER_WORKDIR}/public ./public # Copy package.json for script definitions (lock file should not be needed) diff --git a/backend/jest.config.js b/backend/jest.config.js index 39170c09f..3cee980c5 100644 --- a/backend/jest.config.js +++ b/backend/jest.config.js @@ -4,4 +4,7 @@ module.exports = { preset: 'ts-jest', collectCoverage: true, collectCoverageFrom: ['src/**/*.ts', '!**/node_modules/**'], + moduleNameMapper: { + '@entity/(.*)': '/../database/entity/$1', + }, } diff --git a/backend/package.json b/backend/package.json index 057921215..7b08be989 100644 --- a/backend/package.json +++ b/backend/package.json @@ -28,11 +28,12 @@ "jest": "^27.2.4", "jsonwebtoken": "^8.5.1", "libsodium-wrappers": "^0.7.9", + "module-alias": "^2.2.2", "mysql2": "^2.3.0", "reflect-metadata": "^0.1.13", "ts-jest": "^27.0.5", "type-graphql": "^1.1.1", - "typeorm": "^0.2.37" + "typeorm": "^0.2.38" }, "devDependencies": { "@types/express": "^4.17.12", @@ -51,5 +52,8 @@ "prettier": "^2.3.1", "ts-node": "^10.0.0", "typescript": "^4.3.4" + }, + "_moduleAliases": { + "@entity" : "../database/build/entity" } } diff --git a/backend/src/graphql/resolver/TransactionResolver.ts b/backend/src/graphql/resolver/TransactionResolver.ts index 644a213e6..cb517ebe6 100644 --- a/backend/src/graphql/resolver/TransactionResolver.ts +++ b/backend/src/graphql/resolver/TransactionResolver.ts @@ -19,12 +19,12 @@ import { UserRepository } from '../../typeorm/repository/User' import { UserTransactionRepository } from '../../typeorm/repository/UserTransaction' import { TransactionRepository } from '../../typeorm/repository/Transaction' -import { User as dbUser } from '../../typeorm/entity/User' -import { UserTransaction as dbUserTransaction } from '../../typeorm/entity/UserTransaction' -import { Transaction as dbTransaction } from '../../typeorm/entity/Transaction' +import { User as dbUser } from '@entity/User' +import { UserTransaction as dbUserTransaction } from '@entity/UserTransaction' +import { Transaction as dbTransaction } from '@entity/Transaction' import { apiPost } from '../../apis/HttpRequest' -import { roundFloorFrom4 } from '../../util/round' +import { roundFloorFrom4, roundCeilFrom4 } from '../../util/round' import { calculateDecay, calculateDecayWithInterval } from '../../util/decay' import { TransactionTypeId } from '../enum/TransactionTypeId' import { TransactionType } from '../enum/TransactionType' @@ -150,7 +150,7 @@ async function calculateAndAddDecayTransactions( const decayTransaction = new Transaction() decayTransaction.type = 'decay' - decayTransaction.balance = roundFloorFrom4(balance) + decayTransaction.balance = roundCeilFrom4(balance) decayTransaction.decayDuration = decay.decayDuration decayTransaction.decayStart = decay.decayStart decayTransaction.decayEnd = decay.decayEnd diff --git a/backend/src/graphql/resolver/UserResolver.ts b/backend/src/graphql/resolver/UserResolver.ts index 64632f366..33949197c 100644 --- a/backend/src/graphql/resolver/UserResolver.ts +++ b/backend/src/graphql/resolver/UserResolver.ts @@ -9,7 +9,7 @@ import { LoginViaVerificationCode } from '../model/LoginViaVerificationCode' import { SendPasswordResetEmailResponse } from '../model/SendPasswordResetEmailResponse' import { UpdateUserInfosResponse } from '../model/UpdateUserInfosResponse' import { User } from '../model/User' -import { User as DbUser } from '../../typeorm/entity/User' +import { User as DbUser } from '@entity/User' import encode from '../../jwt/encode' import ChangePasswordArgs from '../arg/ChangePasswordArgs' import CheckUsernameArgs from '../arg/CheckUsernameArgs' diff --git a/backend/src/typeorm/connection.ts b/backend/src/typeorm/connection.ts index 857e76d47..5709c29b6 100644 --- a/backend/src/typeorm/connection.ts +++ b/backend/src/typeorm/connection.ts @@ -1,6 +1,6 @@ import { createConnection, Connection } from 'typeorm' import CONFIG from '../config' -import path from 'path' +import { entities } from '@entity/index' const connection = async (): Promise => { let con = null @@ -13,7 +13,7 @@ const connection = async (): Promise => { username: CONFIG.DB_USER, password: CONFIG.DB_PASSWORD, database: CONFIG.DB_DATABASE, - entities: [path.join(__dirname, 'entity', '*.{ts,js}')], + entities, synchronize: false, }) } catch (error) { diff --git a/backend/src/typeorm/getDBVersion.ts b/backend/src/typeorm/getDBVersion.ts index 32f0ab90d..a64a6c2b7 100644 --- a/backend/src/typeorm/getDBVersion.ts +++ b/backend/src/typeorm/getDBVersion.ts @@ -1,10 +1,13 @@ -import { Migration } from './entity/Migration' +import { getRepository } from 'typeorm' +import { Migration } from '@entity/Migration' const getDBVersion = async (): Promise => { try { - const dbVersion = await Migration.findOne({ order: { version: 'DESC' } }) + const dbVersion = await getRepository(Migration).findOne({ order: { version: 'DESC' } }) return dbVersion ? dbVersion.fileName : null } catch (error) { + // eslint-disable-next-line no-console + console.log(error) return null } } diff --git a/backend/src/typeorm/repository/Balance.ts b/backend/src/typeorm/repository/Balance.ts index 0938191e0..b7c20650f 100644 --- a/backend/src/typeorm/repository/Balance.ts +++ b/backend/src/typeorm/repository/Balance.ts @@ -1,5 +1,5 @@ import { EntityRepository, Repository } from 'typeorm' -import { Balance } from '../entity/Balance' +import { Balance } from '@entity/Balance' @EntityRepository(Balance) export class BalanceRepository extends Repository { diff --git a/backend/src/typeorm/repository/Transaction.ts b/backend/src/typeorm/repository/Transaction.ts index 2c26fe7b5..ab4e301c7 100644 --- a/backend/src/typeorm/repository/Transaction.ts +++ b/backend/src/typeorm/repository/Transaction.ts @@ -1,5 +1,5 @@ import { EntityRepository, Repository } from 'typeorm' -import { Transaction } from '../entity/Transaction' +import { Transaction } from '@entity/Transaction' @EntityRepository(Transaction) export class TransactionRepository extends Repository { diff --git a/backend/src/typeorm/repository/User.ts b/backend/src/typeorm/repository/User.ts index 86f7119c4..441c1b2c8 100644 --- a/backend/src/typeorm/repository/User.ts +++ b/backend/src/typeorm/repository/User.ts @@ -1,5 +1,5 @@ import { EntityRepository, Repository } from 'typeorm' -import { User } from '../entity/User' +import { User } from '@entity/User' @EntityRepository(User) export class UserRepository extends Repository { diff --git a/backend/src/typeorm/repository/UserSettingRepository.ts b/backend/src/typeorm/repository/UserSettingRepository.ts index 81dde702a..80c44802b 100644 --- a/backend/src/typeorm/repository/UserSettingRepository.ts +++ b/backend/src/typeorm/repository/UserSettingRepository.ts @@ -1,5 +1,5 @@ import { EntityRepository, Repository } from 'typeorm' -import { UserSetting } from '../entity/UserSetting' +import { UserSetting } from '@entity/UserSetting' import { Setting } from '../../graphql/enum/Setting' import { isStringBoolean } from '../../util/validate' diff --git a/backend/src/typeorm/repository/UserTransaction.ts b/backend/src/typeorm/repository/UserTransaction.ts index 58fe8d3e7..95362c0c6 100644 --- a/backend/src/typeorm/repository/UserTransaction.ts +++ b/backend/src/typeorm/repository/UserTransaction.ts @@ -1,6 +1,6 @@ import { EntityRepository, Repository } from 'typeorm' import { Order } from '../../graphql/enum/Order' -import { UserTransaction } from '../entity/UserTransaction' +import { UserTransaction } from '@entity/UserTransaction' @EntityRepository(UserTransaction) export class UserTransactionRepository extends Repository { diff --git a/backend/tsconfig.json b/backend/tsconfig.json index 432297d60..73e00a1a0 100644 --- a/backend/tsconfig.json +++ b/backend/tsconfig.json @@ -46,7 +46,9 @@ /* Module Resolution Options */ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ - // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + "paths": { /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + "@entity/*": ["../database/entity/*"] + }, // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ @@ -68,5 +70,12 @@ /* Advanced Options */ "skipLibCheck": true, /* Skip type checking of declaration files. */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ - } + }, + "references": [ + { + "path": "../database/tsconfig.json", + // add 'prepend' if you want to include the referenced project in your output file + // "prepend": true, + } + ] } diff --git a/backend/yarn.lock b/backend/yarn.lock index c8efefc77..091cd7038 100644 --- a/backend/yarn.lock +++ b/backend/yarn.lock @@ -4123,6 +4123,11 @@ mkdirp@^1.0.4: resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +module-alias@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/module-alias/-/module-alias-2.2.2.tgz#151cdcecc24e25739ff0aa6e51e1c5716974c0e0" + integrity sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q== + ms@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz" @@ -5374,10 +5379,10 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" -typeorm@^0.2.37: - version "0.2.37" - resolved "https://registry.npmjs.org/typeorm/-/typeorm-0.2.37.tgz" - integrity sha512-7rkW0yCgFC24I5T0f3S/twmLSuccPh1SQmxET/oDWn2sSDVzbyWdnItSdKy27CdJGTlKHYtUVeOcMYw5LRsXVw== +typeorm@^0.2.38: + version "0.2.38" + resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.38.tgz#2af08079919f6ab04cd17017f9faa2c8d5cd566f" + integrity sha512-M6Y3KQcAREQcphOVJciywf4mv6+A0I/SeR+lWNjKsjnQ+a3XcMwGYMGL0Jonsx3H0Cqlf/3yYqVki1jIXSK/xg== dependencies: "@sqltools/formatter" "^1.2.2" app-root-path "^3.0.0" diff --git a/community_server/src/Controller/ServerUsersController.php b/community_server/src/Controller/ServerUsersController.php index 236e35b7f..c07808641 100644 --- a/community_server/src/Controller/ServerUsersController.php +++ b/community_server/src/Controller/ServerUsersController.php @@ -15,7 +15,8 @@ class ServerUsersController extends AppController public function initialize() { parent::initialize(); - $this->Auth->allow(['add', 'edit']); + // uncomment in devmode to add new community server admin user, but don't!!! commit it + //$this->Auth->allow(['add', 'edit']); $this->Auth->deny('index'); } diff --git a/configs/login_server/grd_login.properties b/configs/login_server/grd_login.properties index 96b0ea928..74424328e 100644 --- a/configs/login_server/grd_login.properties +++ b/configs/login_server/grd_login.properties @@ -17,7 +17,7 @@ phpServer.host = nginx loginServer.path = http://localhost/account loginServer.default_locale = de loginServer.db.host = mariadb -loginServer.db.name = gradido_login +loginServer.db.name = gradido_community loginServer.db.user = root loginServer.db.password = loginServer.db.port = 3306 diff --git a/configs/login_server/grd_login_test.properties b/configs/login_server/grd_login_test.properties index 8a269694a..65aa0c5d0 100644 --- a/configs/login_server/grd_login_test.properties +++ b/configs/login_server/grd_login_test.properties @@ -17,7 +17,7 @@ phpServer.host = nginx loginServer.path = http://localhost/account loginServer.default_locale = de loginServer.db.host = mariadb -loginServer.db.name = gradido_login_test +loginServer.db.name = gradido_community_test loginServer.db.user = root loginServer.db.password = loginServer.db.port = 3306 diff --git a/configs/login_server/setup_db_tables/setup_docker_group.sql b/configs/login_server/setup_db_tables/setup_docker_group.sql deleted file mode 100644 index 5f1b64c3f..000000000 --- a/configs/login_server/setup_db_tables/setup_docker_group.sql +++ /dev/null @@ -1,6 +0,0 @@ -INSERT INTO `groups` (`id`, `alias`, `name`, `url`, `host`, `home`, `description`) VALUES -(1, 'docker', 'docker gradido group', 'localhost', 'nginx', '/', 'gradido test group for docker and stage2 with blockchain db'); - - - - diff --git a/database/Dockerfile b/database/Dockerfile index 1b30e9c0c..fe3d5ab9f 100644 --- a/database/Dockerfile +++ b/database/Dockerfile @@ -73,7 +73,7 @@ RUN yarn run build FROM build as test_up # Run command -CMD /bin/sh -c "yarn run dev_up" +CMD /bin/sh -c "yarn install && yarn run dev_up" ################################################################################## # TEST RESET ##################################################################### @@ -81,7 +81,7 @@ CMD /bin/sh -c "yarn run dev_up" FROM build as test_reset # Run command -CMD /bin/sh -c "yarn run dev_reset" +CMD /bin/sh -c "yarn install && yarn run dev_reset" ################################################################################## # TEST DOWN ###################################################################### @@ -89,7 +89,7 @@ CMD /bin/sh -c "yarn run dev_reset" FROM build as test_down # Run command -CMD /bin/sh -c "yarn run dev_down" +CMD /bin/sh -c "yarn install && yarn run dev_down" ################################################################################## # PRODUCTION (Does contain only "binary"- and static-files to reduce image size) # diff --git a/backend/src/typeorm/entity/Balance.ts b/database/entity/0001-init_db/Balance.ts similarity index 100% rename from backend/src/typeorm/entity/Balance.ts rename to database/entity/0001-init_db/Balance.ts diff --git a/backend/src/typeorm/entity/Migration.ts b/database/entity/0001-init_db/Migration.ts similarity index 100% rename from backend/src/typeorm/entity/Migration.ts rename to database/entity/0001-init_db/Migration.ts diff --git a/backend/src/typeorm/entity/Transaction.ts b/database/entity/0001-init_db/Transaction.ts similarity index 100% rename from backend/src/typeorm/entity/Transaction.ts rename to database/entity/0001-init_db/Transaction.ts diff --git a/backend/src/typeorm/entity/TransactionCreation.ts b/database/entity/0001-init_db/TransactionCreation.ts similarity index 100% rename from backend/src/typeorm/entity/TransactionCreation.ts rename to database/entity/0001-init_db/TransactionCreation.ts diff --git a/backend/src/typeorm/entity/TransactionSendCoin.ts b/database/entity/0001-init_db/TransactionSendCoin.ts similarity index 100% rename from backend/src/typeorm/entity/TransactionSendCoin.ts rename to database/entity/0001-init_db/TransactionSendCoin.ts diff --git a/database/entity/0001-init_db/User.ts b/database/entity/0001-init_db/User.ts new file mode 100644 index 000000000..d76711eb1 --- /dev/null +++ b/database/entity/0001-init_db/User.ts @@ -0,0 +1,26 @@ +import { BaseEntity, Entity, PrimaryGeneratedColumn, Column } from 'typeorm' + +// Moriz: I do not like the idea of having two user tables +@Entity('state_users') +export class User extends BaseEntity { + @PrimaryGeneratedColumn() + id: number + + @Column({ type: 'binary', length: 32, name: 'public_key' }) + pubkey: Buffer + + @Column() + email: string + + @Column({ name: 'first_name' }) + firstName: string + + @Column({ name: 'last_name' }) + lastName: string + + @Column() + username: string + + @Column() + disabled: boolean +} diff --git a/backend/src/typeorm/entity/UserTransaction.ts b/database/entity/0001-init_db/UserTransaction.ts similarity index 100% rename from backend/src/typeorm/entity/UserTransaction.ts rename to database/entity/0001-init_db/UserTransaction.ts diff --git a/backend/src/typeorm/entity/User.ts b/database/entity/0002-add_settings/User.ts similarity index 89% rename from backend/src/typeorm/entity/User.ts rename to database/entity/0002-add_settings/User.ts index e30fee725..51bbef164 100644 --- a/backend/src/typeorm/entity/User.ts +++ b/database/entity/0002-add_settings/User.ts @@ -7,9 +7,6 @@ export class User extends BaseEntity { @PrimaryGeneratedColumn() id: number - // @ManyToOne(type => Group, group => group.users) - // group: Group; - @Column({ type: 'binary', length: 32, name: 'public_key' }) pubkey: Buffer diff --git a/backend/src/typeorm/entity/UserSetting.ts b/database/entity/0002-add_settings/UserSetting.ts similarity index 100% rename from backend/src/typeorm/entity/UserSetting.ts rename to database/entity/0002-add_settings/UserSetting.ts diff --git a/database/entity/Balance.ts b/database/entity/Balance.ts new file mode 100644 index 000000000..c4fde6334 --- /dev/null +++ b/database/entity/Balance.ts @@ -0,0 +1 @@ +export { Balance } from './0001-init_db/Balance' diff --git a/database/entity/Migration.ts b/database/entity/Migration.ts new file mode 100644 index 000000000..9f1e743d0 --- /dev/null +++ b/database/entity/Migration.ts @@ -0,0 +1 @@ +export { Migration } from './0001-init_db/Migration' diff --git a/database/entity/Transaction.ts b/database/entity/Transaction.ts new file mode 100644 index 000000000..d3915c05d --- /dev/null +++ b/database/entity/Transaction.ts @@ -0,0 +1 @@ +export { Transaction } from './0001-init_db/Transaction' diff --git a/database/entity/TransactionCreation.ts b/database/entity/TransactionCreation.ts new file mode 100644 index 000000000..100e948a1 --- /dev/null +++ b/database/entity/TransactionCreation.ts @@ -0,0 +1 @@ +export { TransactionCreation } from './0001-init_db/TransactionCreation' diff --git a/database/entity/TransactionSendCoin.ts b/database/entity/TransactionSendCoin.ts new file mode 100644 index 000000000..5c47d3961 --- /dev/null +++ b/database/entity/TransactionSendCoin.ts @@ -0,0 +1 @@ +export { TransactionSendCoin } from './0001-init_db/TransactionSendCoin' diff --git a/database/entity/User.ts b/database/entity/User.ts new file mode 100644 index 000000000..b20e934f1 --- /dev/null +++ b/database/entity/User.ts @@ -0,0 +1 @@ +export { User } from './0002-add_settings/User' diff --git a/database/entity/UserSetting.ts b/database/entity/UserSetting.ts new file mode 100644 index 000000000..38da380f9 --- /dev/null +++ b/database/entity/UserSetting.ts @@ -0,0 +1 @@ +export { UserSetting } from './0002-add_settings/UserSetting' diff --git a/database/entity/UserTransaction.ts b/database/entity/UserTransaction.ts new file mode 100644 index 000000000..bcbe6a65a --- /dev/null +++ b/database/entity/UserTransaction.ts @@ -0,0 +1 @@ +export { UserTransaction } from './0001-init_db/UserTransaction' diff --git a/database/entity/index.ts b/database/entity/index.ts new file mode 100644 index 000000000..e18757ab8 --- /dev/null +++ b/database/entity/index.ts @@ -0,0 +1,19 @@ +import { Balance } from './Balance' +import { Migration } from './Migration' +import { Transaction } from './Transaction' +import { TransactionCreation } from './TransactionCreation' +import { TransactionSendCoin } from './TransactionSendCoin' +import { User } from './User' +import { UserSetting } from './UserSetting' +import { UserTransaction } from './UserTransaction' + +export const entities = [ + Balance, + Migration, + Transaction, + TransactionCreation, + TransactionSendCoin, + User, + UserSetting, + UserTransaction, +] diff --git a/database/migrations/0002-add_settings.ts b/database/migrations/0002-add_settings.ts index 68c340040..d26a2b4cc 100644 --- a/database/migrations/0002-add_settings.ts +++ b/database/migrations/0002-add_settings.ts @@ -11,7 +11,7 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { await queryFn(` - CREATE TABLE IF NOT EXISTS \`user_setting\` ( + CREATE TABLE \`user_setting\` ( \`id\` int(10) unsigned NOT NULL AUTO_INCREMENT, \`userId\` int(11) NOT NULL, \`key\` varchar(255) NOT NULL, @@ -22,5 +22,5 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { // write downgrade logic as parameter of queryFn - await queryFn(`DROP TABLE IF EXISTS \`user_setting\`;`) + await queryFn(`DROP TABLE \`user_setting\`;`) } diff --git a/database/migrations/0003-login_server_tables.ts b/database/migrations/0003-login_server_tables.ts new file mode 100644 index 000000000..dacc211ac --- /dev/null +++ b/database/migrations/0003-login_server_tables.ts @@ -0,0 +1,153 @@ +/* FIRST MIGRATION + * + * This migration is special since it takes into account that + * the database can be setup already but also may not be. + * Therefore you will find all `CREATE TABLE` statements with + * a `IF NOT EXISTS`, all `INSERT` with an `IGNORE` and in the + * downgrade function all `DROP TABLE` with a `IF EXISTS`. + * This ensures compatibility for existing or non-existing + * databases. + */ + +export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { + await queryFn(` + CREATE TABLE \`login_app_access_tokens\` ( + \`id\` int unsigned NOT NULL AUTO_INCREMENT, + \`user_id\` int NOT NULL, + \`access_code\` bigint unsigned NOT NULL, + \`created\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + \`updated\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (\`id\`), + UNIQUE KEY \`access_code\` (\`access_code\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + `) + await queryFn(` + CREATE TABLE \`login_elopage_buys\` ( + \`id\` int unsigned NOT NULL AUTO_INCREMENT, + \`elopage_user_id\` int DEFAULT NULL, + \`affiliate_program_id\` int NOT NULL, + \`publisher_id\` int NOT NULL, + \`order_id\` int NOT NULL, + \`product_id\` int NOT NULL, + \`product_price\` int NOT NULL, + \`payer_email\` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, + \`publisher_email\` varchar(255) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL, + \`payed\` tinyint NOT NULL, + \`success_date\` datetime NOT NULL, + \`event\` varchar(255) NOT NULL, + PRIMARY KEY (\`id\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + `) + await queryFn(` + CREATE TABLE \`login_email_opt_in_types\` ( + \`id\` int unsigned NOT NULL AUTO_INCREMENT, + \`name\` varchar(255) NOT NULL, + \`description\` varchar(255) NOT NULL, + PRIMARY KEY (\`id\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + `) + await queryFn(` + CREATE TABLE \`login_email_opt_in\` ( + \`id\` int unsigned NOT NULL AUTO_INCREMENT, + \`user_id\` int NOT NULL, + \`verification_code\` bigint unsigned NOT NULL, + \`email_opt_in_type_id\` int NOT NULL, + \`created\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + \`resend_count\` int DEFAULT '0', + \`updated\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, + PRIMARY KEY (\`id\`), + UNIQUE KEY \`verification_code\` (\`verification_code\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + `) + await queryFn(` + CREATE TABLE \`login_groups\` ( + \`id\` int unsigned NOT NULL AUTO_INCREMENT, + \`alias\` varchar(190) NOT NULL, + \`name\` varchar(255) NOT NULL, + \`url\` varchar(255) NOT NULL, + \`host\` varchar(255) DEFAULT "/", + \`home\` varchar(255) DEFAULT "/", + \`description\` text, + PRIMARY KEY (\`id\`), + UNIQUE KEY \`alias\` (\`alias\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + `) + await queryFn(` + CREATE TABLE \`login_pending_tasks\` ( + \`id\` int UNSIGNED NOT NULL AUTO_INCREMENT, + \`user_id\` int UNSIGNED DEFAULT 0, + \`request\` varbinary(2048) NOT NULL, + \`created\` datetime NOT NULL, + \`finished\` datetime DEFAULT '2000-01-01 000000', + \`result_json\` text DEFAULT NULL, + \`param_json\` text DEFAULT NULL, + \`task_type_id\` int UNSIGNED NOT NULL, + \`child_pending_task_id\` int UNSIGNED DEFAULT 0, + \`parent_pending_task_id\` int UNSIGNED DEFAULT 0, + PRIMARY KEY (\`id\`) + ) ENGINE = InnoDB DEFAULT CHARSET=utf8mb4; + `) + await queryFn(` + CREATE TABLE \`login_roles\` ( + \`id\` int unsigned NOT NULL AUTO_INCREMENT, + \`name\` varchar(255) NOT NULL, + \`description\` varchar(255) NOT NULL, + \`flags\` bigint NOT NULL DEFAULT '0', + PRIMARY KEY (\`id\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + `) + await queryFn(` + CREATE TABLE \`login_user_backups\` ( + \`id\` int unsigned NOT NULL AUTO_INCREMENT, + \`user_id\` int NOT NULL, + \`passphrase\` text NOT NULL, + \`mnemonic_type\` int DEFAULT '-1', + PRIMARY KEY (\`id\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + `) + await queryFn(` + CREATE TABLE \`login_user_roles\` ( + \`id\` int unsigned NOT NULL AUTO_INCREMENT, + \`user_id\` int NOT NULL, + \`role_id\` int NOT NULL, + PRIMARY KEY (\`id\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + `) + await queryFn(` + CREATE TABLE \`login_users\` ( + \`id\` int unsigned NOT NULL AUTO_INCREMENT, + \`email\` varchar(191) NOT NULL, + \`first_name\` varchar(150) NOT NULL, + \`last_name\` varchar(255) DEFAULT '', + \`username\` varchar(255) DEFAULT '', + \`description\` text DEFAULT '', + \`password\` bigint unsigned DEFAULT '0', + \`pubkey\` binary(32) DEFAULT NULL, + \`privkey\` binary(80) DEFAULT NULL, + \`email_hash\` binary(32) DEFAULT NULL, + \`created\` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, + \`email_checked\` tinyint NOT NULL DEFAULT '0', + \`passphrase_shown\` tinyint NOT NULL DEFAULT '0', + \`language\` varchar(4) NOT NULL DEFAULT 'de', + \`disabled\` tinyint DEFAULT '0', + \`group_id\` int unsigned DEFAULT 0, + \`publisher_id\` int DEFAULT 0, + PRIMARY KEY (\`id\`), + UNIQUE KEY \`email\` (\`email\`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4; + `) +} + +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + // write downgrade logic as parameter of queryFn + await queryFn(`DROP TABLE \`login_app_access_tokens\`;`) + await queryFn(`DROP TABLE \`login_elopage_buys\`;`) + await queryFn(`DROP TABLE \`login_email_opt_in_types\`;`) + await queryFn(`DROP TABLE \`login_email_opt_in\`;`) + await queryFn(`DROP TABLE \`login_groups\`;`) + await queryFn(`DROP TABLE \`login_pending_tasks\`;`) + await queryFn(`DROP TABLE \`login_roles\`;`) + await queryFn(`DROP TABLE \`login_user_backups\`;`) + await queryFn(`DROP TABLE \`login_user_roles\`;`) + await queryFn(`DROP TABLE \`login_users\`;`) +} diff --git a/database/migrations/0004-login_server_data.ts b/database/migrations/0004-login_server_data.ts new file mode 100644 index 000000000..dad7d1e34 --- /dev/null +++ b/database/migrations/0004-login_server_data.ts @@ -0,0 +1,74 @@ +/* FIRST MIGRATION + * + * This migration is special since it takes into account that + * the database can be setup already but also may not be. + * Therefore you will find all `CREATE TABLE` statements with + * a `IF NOT EXISTS`, all `INSERT` with an `IGNORE` and in the + * downgrade function all `DROP TABLE` with a `IF EXISTS`. + * This ensures compatibility for existing or non-existing + * databases. + */ + +const LOGIN_SERVER_DB = 'gradido_login' + +export async function upgrade(queryFn: (query: string, values?: any[]) => Promise>) { + const loginDatabaseExists = await queryFn(` + SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA WHERE SCHEMA_NAME = '${LOGIN_SERVER_DB}' + `) + if (loginDatabaseExists.length === 0) { + // eslint-disable-next-line no-console + console.log(`Skipping Login Server Database migration - Database ${LOGIN_SERVER_DB} not found`) + return + } + + await queryFn(` + INSERT INTO \`login_app_access_tokens\` SELECT * FROM ${LOGIN_SERVER_DB}.\`app_access_tokens\`; + `) + await queryFn(` + INSERT INTO \`login_elopage_buys\` SELECT * FROM ${LOGIN_SERVER_DB}.\`elopage_buys\`; + `) + await queryFn(` + INSERT INTO \`login_email_opt_in_types\` SELECT * FROM ${LOGIN_SERVER_DB}.\`email_opt_in_types\`; + `) + await queryFn(` + INSERT INTO \`login_email_opt_in\` SELECT * FROM ${LOGIN_SERVER_DB}.\`email_opt_in\`; + `) + await queryFn(` + INSERT INTO \`login_groups\` SELECT * FROM ${LOGIN_SERVER_DB}.\`groups\`; + `) + await queryFn(` + INSERT INTO \`login_pending_tasks\` SELECT * FROM ${LOGIN_SERVER_DB}.\`pending_tasks\`; + `) + await queryFn(` + INSERT INTO \`login_roles\` SELECT * FROM ${LOGIN_SERVER_DB}.\`roles\`; + `) + await queryFn(` + INSERT INTO \`login_user_backups\` SELECT * FROM ${LOGIN_SERVER_DB}.\`user_backups\`; + `) + await queryFn(` + INSERT INTO \`login_user_roles\` SELECT * FROM ${LOGIN_SERVER_DB}.\`user_roles\`; + `) + await queryFn(` + INSERT INTO \`login_users\` SELECT * FROM ${LOGIN_SERVER_DB}.\`users\`; + `) + + // TODO clarify if we need this on non docker environment? + await queryFn(` + INSERT IGNORE INTO \`login_groups\` (\`id\`, \`alias\`, \`name\`, \`url\`, \`host\`, \`home\`, \`description\`) VALUES + (1, 'docker', 'docker gradido group', 'localhost', 'nginx', '/', 'gradido test group for docker and stage2 with blockchain db'); + `) +} + +export async function downgrade(queryFn: (query: string, values?: any[]) => Promise>) { + // write downgrade logic as parameter of queryFn + await queryFn(`DELETE FROM \`login_app_access_tokens\`;`) + await queryFn(`DELETE FROM \`login_elopage_buys\`;`) + await queryFn(`DELETE FROM \`login_email_opt_in_types\`;`) + await queryFn(`DELETE FROM \`login_email_opt_in\`;`) + await queryFn(`DELETE FROM \`login_groups\`;`) + await queryFn(`DELETE FROM \`login_pending_tasks\`;`) + await queryFn(`DELETE FROM \`login_roles\`;`) + await queryFn(`DELETE FROM \`login_user_backups\`;`) + await queryFn(`DELETE FROM \`login_user_roles\`;`) + await queryFn(`DELETE FROM \`login_users\`;`) +} diff --git a/database/package.json b/database/package.json index 4656dab43..c01c75f2b 100644 --- a/database/package.json +++ b/database/package.json @@ -19,7 +19,7 @@ "lint": "eslint . --ext .js,.ts" }, "devDependencies": { - "@types/node": "^16.7.1", + "@types/node": "^16.10.3", "@typescript-eslint/eslint-plugin": "^4.29.2", "@typescript-eslint/parser": "^4.29.2", "eslint": "^7.32.0", @@ -37,6 +37,8 @@ "dependencies": { "dotenv": "^10.0.0", "mysql2": "^2.3.0", - "ts-mysql-migrate": "^1.0.2" + "reflect-metadata": "^0.1.13", + "ts-mysql-migrate": "^1.0.2", + "typeorm": "^0.2.38" } } diff --git a/database/src/index.ts b/database/src/index.ts index eec6712f6..2492a1306 100644 --- a/database/src/index.ts +++ b/database/src/index.ts @@ -1,13 +1,15 @@ +import 'reflect-metadata' import { createPool, PoolConfig } from 'mysql' import { Migration } from 'ts-mysql-migrate' import CONFIG from './config' import prepare from './prepare' +import connection from './typeorm/connection' const run = async (command: string) => { // Database actions not supported by our migration library await prepare() - // Database connection + // Database connection for Migrations const poolConfig: PoolConfig = { host: CONFIG.DB_HOST, port: CONFIG.DB_PORT, @@ -26,6 +28,12 @@ const run = async (command: string) => { dir: CONFIG.MIGRATIONS_DIRECTORY, }) + // Database connection for TypeORM + const con = await connection() + if (!con || !con.isConnected) { + throw new Error(`Couldn't open connection to database`) + } + await migration.initialize() // Execute command @@ -42,6 +50,10 @@ const run = async (command: string) => { default: throw new Error(`Unsupported command ${command}`) } + + // Terminate connections gracefully + await con.close() + pool.end() } run(process.argv[2]) diff --git a/database/src/typeorm/connection.ts b/database/src/typeorm/connection.ts new file mode 100644 index 000000000..e3434c3aa --- /dev/null +++ b/database/src/typeorm/connection.ts @@ -0,0 +1,27 @@ +import { createConnection, Connection } from 'typeorm' +import CONFIG from '../config' +import { entities } from '../../entity/index' + +const connection = async (): Promise => { + let con = null + try { + con = await createConnection({ + name: 'default', + type: 'mysql', + host: CONFIG.DB_HOST, + port: CONFIG.DB_PORT, + username: CONFIG.DB_USER, + password: CONFIG.DB_PASSWORD, + database: CONFIG.DB_DATABASE, + entities, + synchronize: false, + }) + } catch (error) { + // eslint-disable-next-line no-console + console.log(error) + } + + return con +} + +export default connection diff --git a/database/tsconfig.json b/database/tsconfig.json index d48524ba5..445b9d11f 100644 --- a/database/tsconfig.json +++ b/database/tsconfig.json @@ -4,19 +4,19 @@ /* Basic Options */ // "incremental": true, /* Enable incremental compilation */ - "target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */ + "target": "es6", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019', 'ES2020', 'ES2021', or 'ESNEXT'. */ "module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', 'es2020', or 'ESNext'. */ // "lib": [], /* Specify library files to be included in the compilation. */ // "allowJs": true, /* Allow javascript files to be compiled. */ // "checkJs": true, /* Report errors in .js files. */ // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', 'react', 'react-jsx' or 'react-jsxdev'. */ - // "declaration": true, /* Generates corresponding '.d.ts' file. */ - // "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ + "declaration": true, /* Generates corresponding '.d.ts' file. */ + "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */ // "sourceMap": true, /* Generates corresponding '.map' file. */ - // "outFile": "./", /* Concatenate and emit output to single file. */ + // "outFile": "./build/outfile.js", /* Concatenate and emit output to single file. */ "outDir": "./build", /* Redirect output structure to the directory. */ // "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ - // "composite": true, /* Enable project compilation */ + "composite": true, /* Enable project compilation */ // "tsBuildInfoFile": "./", /* Specify file to store incremental compilation information */ // "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ @@ -47,7 +47,7 @@ // "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ - // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "rootDirs": [".", "../database"], /* List of root folders whose combined content represents the structure of the project at runtime. */ // "typeRoots": [], /* List of folders to include type definitions from. */ // "types": [], /* Type declaration files to be included in compilation. */ // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ @@ -68,5 +68,6 @@ /* Advanced Options */ "skipLibCheck": true, /* Skip type checking of declaration files. */ "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */ - } + }, + "references": [] /* Any project that is referenced must itself have a `references` array (which may be empty). */ } diff --git a/database/yarn.lock b/database/yarn.lock index eab1a9844..1afbc7f09 100644 --- a/database/yarn.lock +++ b/database/yarn.lock @@ -90,6 +90,11 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== +"@sqltools/formatter@^1.2.2": + version "1.2.3" + resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.3.tgz#1185726610acc37317ddab11c3c7f9066966bd20" + integrity sha512-O3uyB/JbkAEMZaP3YqyHH7TMnex7tWyCbCI4EfJdOCoN6HIhqdJBWTM6aCCiWQ/5f5wxjgU735QAIpJbjDvmzg== + "@szmarczak/http-timer@^1.1.2": version "1.1.2" resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-1.1.2.tgz#b1665e2c461a2cd92f4c1bbf50d5454de0d4b421" @@ -129,11 +134,21 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@^16.7.1": +"@types/node@*": version "16.7.1" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.7.1.tgz#c6b9198178da504dfca1fd0be9b2e1002f1586f0" integrity sha512-ncRdc45SoYJ2H4eWU9ReDfp3vtFqDYhjOsKlFFUDEn8V1Bgr2RjYal8YT5byfadWIRluhPFU6JiDOl0H6Sl87A== +"@types/node@^16.10.3": + version "16.10.3" + resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.3.tgz#7a8f2838603ea314d1d22bb3171d899e15c57bd5" + integrity sha512-ho3Ruq+fFnBrZhUYI46n/bV2GjwzSkwuT4dTf0GkuNFmnb8nq4ny2z9JEVemFi6bdEJanHLlYfy9c6FN9B9McQ== + +"@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== + "@typescript-eslint/eslint-plugin@^4.29.2": version "4.29.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.29.2.tgz#f54dc0a32b8f61c6024ab8755da05363b733838d" @@ -260,6 +275,11 @@ ansi-colors@^4.1.1: resolved "https://registry.yarnpkg.com/ansi-colors/-/ansi-colors-4.1.1.tgz#cbb9ae256bf750af1eab344f229aa27fe94ba348" integrity sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA== +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + integrity sha1-w7M6te42DYbg5ijwRorn7yfWVN8= + ansi-regex@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" @@ -270,6 +290,11 @@ ansi-regex@^5.0.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + integrity sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4= + ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" @@ -284,6 +309,11 @@ ansi-styles@^4.0.0, ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= + anymatch@~3.1.2: version "3.1.2" resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" @@ -292,6 +322,11 @@ anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +app-root-path@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.0.0.tgz#210b6f43873227e18a4b810a032283311555d5ad" + integrity sha512-qMcx+Gy2UZynHjOHOIXPNvpf+9cjvk3cWrBBK7zg4gH9+clobJRb9NGzcT7mQTcV/6Gm/1WelUtqxVXnNlrwcw== + arg@^4.1.0: version "4.1.3" resolved "https://registry.yarnpkg.com/arg/-/arg-4.1.3.tgz#269fc7ad5b8e42cb63c896d5666017261c144089" @@ -304,6 +339,11 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +argparse@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38" + integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q== + array-includes@^3.1.3: version "3.1.3" resolved "https://registry.yarnpkg.com/array-includes/-/array-includes-3.1.3.tgz#c7f619b382ad2afaf5326cddfdc0afc61af7690a" @@ -339,6 +379,11 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + bignumber.js@9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-9.0.0.tgz#805880f84a329b5eac6e7cb6f8274b6d82bdf075" @@ -378,6 +423,14 @@ braces@^3.0.1, braces@~3.0.2: dependencies: fill-range "^7.0.1" +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + cacheable-request@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" @@ -409,6 +462,17 @@ camelcase@^5.3.1: resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== +chalk@^1.1.1: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + integrity sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg= + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + chalk@^2.0.0: version "2.4.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" @@ -426,7 +490,7 @@ chalk@^3.0.0: ansi-styles "^4.1.0" supports-color "^7.1.0" -chalk@^4.0.0: +chalk@^4.0.0, chalk@^4.1.0: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -459,6 +523,27 @@ cli-boxes@^2.2.0: resolved "https://registry.yarnpkg.com/cli-boxes/-/cli-boxes-2.2.1.tgz#ddd5035d25094fce220e9cab40a45840a440318f" integrity sha512-y4coMcylgSCdVinjiDBuR8PCC2bLjyGTwEmPb9NHR/QaNU6EUOXcTY/s6VjGMD6ENSEaeQYHCY0GNGS5jfMwPw== +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" + +cliui@^7.0.2: + version "7.0.4" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-7.0.4.tgz#a0265ee655476fc807aea9df3df8df7783808b4f" + integrity sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^7.0.0" + clone-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" @@ -624,6 +709,11 @@ dotenv@^10.0.0: resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-10.0.0.tgz#3d4227b8fb95f81096cdd2b66653fb2c7085ba81" integrity sha512-rlBi9d8jpv9Sf1klPjNfFAuWDjKLwTIJJ/VxtoTwIR6hnZxcEOQCZg2oIL3MWBYw5GpUDKOEnND7LXTbIpQ03Q== +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== + duplexer3@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" @@ -692,12 +782,17 @@ es-to-primitive@^1.2.1: is-date-object "^1.0.1" is-symbol "^1.0.2" +escalade@^3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40" + integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw== + escape-goat@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/escape-goat/-/escape-goat-2.1.1.tgz#1b2dc77003676c457ec760b2dc68edb648188675" integrity sha512-8/uIhbG12Csjy2JEW7D9pHbreaVaS/OpN3ycnyvElTdwM5n6GY6W6e2IPemfvGZeUMqZ9A/3GqIZMgKnBhAw/Q== -escape-string-regexp@^1.0.5: +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= @@ -945,6 +1040,11 @@ fastq@^1.6.0: dependencies: reusify "^1.0.4" +figlet@^1.1.1: + version "1.5.2" + resolved "https://registry.yarnpkg.com/figlet/-/figlet-1.5.2.tgz#dda34ff233c9a48e36fcff6741aeb5bafe49b634" + integrity sha512-WOn21V8AhyE1QqVfPIVxe3tupJacq1xGkPTB4iagT6o+P2cAgEOOwIxMftr4+ZCTI6d551ij9j61DFr0nsP2uQ== + file-entry-cache@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/file-entry-cache/-/file-entry-cache-6.0.1.tgz#211b2dd9659cb0394b073e7323ac3c933d522027" @@ -1006,6 +1106,11 @@ generate-function@^2.3.1: dependencies: is-property "^1.0.2" +get-caller-file@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-2.0.5.tgz#4f94412a82db32f36e3b0b9741f8a97feb031f7e" + integrity sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg== + get-intrinsic@^1.0.2, get-intrinsic@^1.1.0, get-intrinsic@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/get-intrinsic/-/get-intrinsic-1.1.1.tgz#15f59f376f855c446963948f0d24cd3637b4abc6" @@ -1048,6 +1153,18 @@ glob@^7.1.3: once "^1.3.0" path-is-absolute "^1.0.0" +glob@^7.1.6: + version "7.2.0" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.2.0.tgz#d15535af7732e02e948f4c41628bd910293f6023" + integrity sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q== + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + global-dirs@^2.0.1: version "2.1.0" resolved "https://registry.yarnpkg.com/global-dirs/-/global-dirs-2.1.0.tgz#e9046a49c806ff04d6c1825e196c8f0091e8df4d" @@ -1096,6 +1213,13 @@ graceful-fs@^4.1.2: resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.8.tgz#e412b8d33f5e006593cbd3cee6df9f2cebbe802a" integrity sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg== +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + integrity sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE= + dependencies: + ansi-regex "^2.0.0" + has-bigints@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.1.tgz#64fe6acb020673e3b78db035a5af69aa9d07b113" @@ -1135,6 +1259,11 @@ has@^1.0.3: dependencies: function-bind "^1.1.1" +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== + hosted-git-info@^2.1.4: version "2.8.9" resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz#dffc0bf9a21c02209090f2aa69429e1414daf3f9" @@ -1152,6 +1281,11 @@ iconv-lite@^0.6.2: dependencies: safer-buffer ">= 2.1.2 < 3.0.0" +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + ignore-by-default@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/ignore-by-default/-/ignore-by-default-1.0.1.tgz#48ca6d72f6c6a3af00a9ad4ae6876be3889e2b09" @@ -1193,7 +1327,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@~2.0.3: +inherits@2, inherits@^2.0.1, inherits@~2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -1392,6 +1526,13 @@ js-yaml@^3.13.1: argparse "^1.0.7" esprima "^4.0.0" +js-yaml@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602" + integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA== + dependencies: + argparse "^2.0.1" + json-buffer@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" @@ -1551,6 +1692,11 @@ minimist@^1.2.0, minimist@^1.2.5: resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602" integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw== +mkdirp@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e" + integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== + ms@2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" @@ -1590,6 +1736,15 @@ mysql@^2.18.1: safe-buffer "5.1.2" sqlstring "2.3.1" +mz@^2.4.0: + version "2.7.0" + resolved "https://registry.yarnpkg.com/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + named-placeholders@^1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/named-placeholders/-/named-placeholders-1.1.2.tgz#ceb1fbff50b6b33492b5cf214ccf5e39cef3d0e8" @@ -1645,6 +1800,11 @@ normalize-url@^4.1.0: resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.1.tgz#0dd90cf1288ee1d1313b87081c9a5932ee48518a" integrity sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA== +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + object-inspect@^1.11.0, object-inspect@^1.9.0: version "1.11.0" resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.11.0.tgz#9dceb146cedd4148a0d9e51ab88d34cf509922b1" @@ -1734,6 +1894,11 @@ parent-module@^1.0.0: dependencies: callsites "^3.0.0" +parent-require@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parent-require/-/parent-require-1.0.0.tgz#746a167638083a860b0eef6732cb27ed46c32977" + integrity sha1-dGoWdjgIOoYLDu9nMssn7UbDKXc= + parse-json@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" @@ -1742,6 +1907,23 @@ parse-json@^4.0.0: error-ex "^1.3.1" json-parse-better-errors "^1.0.1" +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@^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@^6.0.1: + version "6.0.1" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b" + integrity sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw== + path-exists@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" @@ -1912,6 +2094,11 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +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== + regexpp@^3.0.0, regexpp@^3.1.0: version "3.2.0" resolved "https://registry.yarnpkg.com/regexpp/-/regexpp-3.2.0.tgz#0425a2768d8f23bad70ca4b90461fa2f1213e1b2" @@ -1931,6 +2118,11 @@ registry-url@^5.0.0: dependencies: rc "^1.2.8" +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + integrity sha1-jGStX9MNqxyXbiNE/+f3kqam30I= + require-from-string@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/require-from-string/-/require-from-string-2.0.2.tgz#89a7fdd938261267318eafe14f9c32e598c36909" @@ -1980,11 +2172,21 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== +safe-buffer@^5.0.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + "safer-buffer@>= 2.1.2 < 3.0.0": version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg== +sax@>=0.6.0: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw== + semver-diff@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/semver-diff/-/semver-diff-3.1.1.tgz#05f77ce59f325e00e2706afd67bb506ddb1ca32b" @@ -2014,6 +2216,14 @@ seq-queue@^0.0.5: resolved "https://registry.yarnpkg.com/seq-queue/-/seq-queue-0.0.5.tgz#d56812e1c017a6e4e7c3e3a37a1da6d78dd3c93e" integrity sha1-1WgS4cAXpuTnw+Ojeh2m143TyT4= +sha.js@^2.4.11: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + integrity sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ== + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -2136,6 +2346,13 @@ string_decoder@~1.1.1: dependencies: safe-buffer "~5.1.0" +strip-ansi@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + integrity sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8= + dependencies: + ansi-regex "^2.0.0" + strip-ansi@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-5.2.0.tgz#8c9a536feb6afc962bdfa5b104a5091c1ad9c0ae" @@ -2165,6 +2382,11 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + integrity sha1-U10EXOa2Nj+kARcIRimZXp3zJMc= + supports-color@^5.3.0, supports-color@^5.5.0: version "5.5.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -2201,6 +2423,20 @@ text-table@^0.2.0: resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.yarnpkg.com/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + to-readable-stream@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-1.0.0.tgz#ce0aa0c2f3df6adf852efb404a783e77c0475771" @@ -2260,6 +2496,11 @@ tslib@^1.8.1: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== +tslib@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.1.tgz#e8a335add5ceae51aa261d32a490158ef042ef01" + integrity sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" @@ -2291,6 +2532,29 @@ typedarray-to-buffer@^3.1.5: dependencies: is-typedarray "^1.0.0" +typeorm@^0.2.38: + version "0.2.38" + resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.2.38.tgz#2af08079919f6ab04cd17017f9faa2c8d5cd566f" + integrity sha512-M6Y3KQcAREQcphOVJciywf4mv6+A0I/SeR+lWNjKsjnQ+a3XcMwGYMGL0Jonsx3H0Cqlf/3yYqVki1jIXSK/xg== + 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" + xml2js "^0.4.23" + yargonaut "^1.1.4" + yargs "^17.0.1" + zen-observable-ts "^1.0.0" + typescript@^4.3.5: version "4.3.5" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" @@ -2401,6 +2665,15 @@ word-wrap@^1.2.3: resolved "https://registry.yarnpkg.com/word-wrap/-/word-wrap-1.2.3.tgz#610636f6b1f703891bd34771ccb17fb93b47079c" integrity sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ== +wrap-ansi@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" + integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -2421,6 +2694,24 @@ xdg-basedir@^4.0.0: resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-4.0.0.tgz#4bc8d9984403696225ef83a1573cbbcb4e79db13" integrity sha512-PSNhEJDejZYV7h50BohL09Er9VaIefr2LMAf3OEmpCkjOi34eYyQYAXUTjEQtZJTKcF0E2UKTh+osDLsgNim9Q== +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== + dependencies: + sax ">=0.6.0" + xmlbuilder "~11.0.0" + +xmlbuilder@~11.0.0: + version "11.0.1" + resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" + integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== + +y18n@^5.0.5: + version "5.0.8" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" + integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== + yallist@^2.1.2: version "2.1.2" resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" @@ -2431,7 +2722,60 @@ yallist@^4.0.0: resolved "https://registry.yarnpkg.com/yallist/-/yallist-4.0.0.tgz#9bb92790d9c0effec63be73519e11a35019a3a72" integrity sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A== +yargonaut@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/yargonaut/-/yargonaut-1.1.4.tgz#c64f56432c7465271221f53f5cc517890c3d6e0c" + integrity sha512-rHgFmbgXAAzl+1nngqOcwEljqHGG9uUZoPjsdZEs1w5JW9RXYzrSvH/u70C1JE5qFi0qjsdhnUX/dJRpWqitSA== + dependencies: + chalk "^1.1.1" + figlet "^1.1.1" + parent-require "^1.0.0" + +yargs-parser@^20.2.2: + version "20.2.9" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.9.tgz#2eb7dc3b0289718fc295f362753845c41a0c94ee" + integrity sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w== + +yargs@^16.0.0: + version "16.2.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66" + integrity sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + +yargs@^17.0.1: + version "17.2.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.2.1.tgz#e2c95b9796a0e1f7f3bf4427863b42e0418191ea" + integrity sha512-XfR8du6ua4K6uLGm5S6fA+FIJom/MdJcFNVY8geLlp2v8GYbOXD4EB1tPNZsRn4vBzKGMgb5DRZMeWuFc2GO8Q== + dependencies: + cliui "^7.0.2" + escalade "^3.1.1" + get-caller-file "^2.0.5" + require-directory "^2.1.1" + string-width "^4.2.0" + y18n "^5.0.5" + yargs-parser "^20.2.2" + yn@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== + +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@0.8.15: + version "0.8.15" + resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15" + integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ== diff --git a/deployment/bare_metal/update_all.sh b/deployment/bare_metal/update_all.sh index b065a16d4..e045d3f39 100755 --- a/deployment/bare_metal/update_all.sh +++ b/deployment/bare_metal/update_all.sh @@ -36,8 +36,6 @@ cd $PROJECT_PATH # git checkout -f master git pull cd deployment/bare_metal -echo 'update schemas' >> $UPDATE_HTML -./update_db_schemas.sh echo 'starting with rebuilding login-server
' >> $UPDATE_HTML ./build_and_start_login_server.sh echo 'starting with rebuilding frontend
' >> $UPDATE_HTML diff --git a/deployment/bare_metal/update_db_schemas.sh b/deployment/bare_metal/update_db_schemas.sh deleted file mode 100755 index 80628f35c..000000000 --- a/deployment/bare_metal/update_db_schemas.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -# For that to work skeema needed to be installed on system -# in login_server/skeema skeema configuration files need to be there also in the subfolders -# Update DB Schemas (only the schemas, not the data) - -cd ../../login_server/skeema -skeema push --allow-unsafe diff --git a/docker-compose.override.yml b/docker-compose.override.yml index d14ce50f5..5783b9fe7 100644 --- a/docker-compose.override.yml +++ b/docker-compose.override.yml @@ -36,8 +36,11 @@ services: # This makes sure the docker container has its own node modules. # Therefore it is possible to have a different node version on the host machine - backend_node_modules:/app/node_modules + - backend_database_node_modules:/database/node_modules + - backend_database_build:/database/build # bind the local folder to the docker to allow live reload - ./backend:/app + - ./database:/database ######################################################## # DATABASE ############################################## @@ -133,25 +136,12 @@ services: - external-net volumes: - /sessions - - ######################################################### - ## skeema for updating dbs if changes happend ########### - ######################################################### - skeema: - build: - context: . - dockerfile: ./skeema/Dockerfile - target: skeema_dev_run - depends_on: - - mariadb - networks: - - internal-net - volumes: - - ./login_server/skeema/gradido_login:/skeema/gradido_login - + volumes: frontend_node_modules: backend_node_modules: + backend_database_node_modules: + backend_database_build: database_node_modules: database_build: login_build_ubuntu_3.1: \ No newline at end of file diff --git a/docker-compose.test.yml b/docker-compose.test.yml index 34a2cafd1..b6ad3eb1f 100644 --- a/docker-compose.test.yml +++ b/docker-compose.test.yml @@ -23,7 +23,7 @@ services: build: context: . dockerfile: ./mariadb/Dockerfile - target: mariadb_server_test + target: mariadb_server environment: - MARIADB_ALLOW_EMPTY_PASSWORD=1 - MARIADB_USER=root @@ -89,19 +89,6 @@ services: - external-net volumes: - /sessions - - ######################################################### - ## skeema for updating dbs if changes happend ########### - ######################################################### - skeema: - build: - context: . - dockerfile: ./skeema/Dockerfile - target: skeema_run - depends_on: - - mariadb - networks: - - internal-net networks: external-net: diff --git a/docker-compose.yml b/docker-compose.yml index 15a47111c..3ce88715d 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -35,9 +35,8 @@ services: ######################################################### mariadb: build: - context: . - dockerfile: ./mariadb/Dockerfile - target: mariadb_server_test + context: ./mariadb + target: mariadb_server environment: - MARIADB_ALLOW_EMPTY_PASSWORD=1 - MARIADB_USER=root @@ -54,7 +53,10 @@ services: backend: image: gradido/backend:latest build: - context: ./backend + # since we have to include the entities from ./database we cannot define the context as ./backend + # this might blow build image size to the moon ?! + context: ./ + dockerfile: ./backend/Dockerfile target: production networks: - internal-net @@ -155,41 +157,6 @@ services: - internal-net volumes: - ./community_server/config/php-fpm/php-ini-overrides.ini:/etc/php/7.4/fpm/conf.d/99-overrides.ini - - ######################################################### - ## skeema for updating dbs if changes happend ########### - ######################################################### - skeema: - build: - context: . - dockerfile: ./skeema/Dockerfile - target: skeema_run - depends_on: - - mariadb - networks: - - internal-net - - ######################################################### - ## GRADIDO NODE v1 ###################################### - ######################################################### - # gradido-node: - # build: - # context: . - # dockerfile: ./gn/docker/deprecated-hedera-node/Dockerfile - # volumes: - # - ${GN_INSTANCE_FOLDER}:/opt/instance - # container_name: ${GN_CONTAINER_NAME} - - ######################################################### - ## GRADIDO NODE test ################################### - ######################################################### - # gradido-node-test: - # build: - # context: . - # dockerfile: ./gn/docker/deprecated-hedera-node/Dockerfile - # container_name: gn-test - # working_dir: /opt/gn/build - # command: ["./unit_tests"] networks: external-net: diff --git a/docu/Concepts/TechnicalRequirements/Architecture/TechnicalOverview.md b/docu/Concepts/TechnicalRequirements/Architecture/TechnicalOverview.md index f0fe1e52a..73f74dbae 100644 --- a/docu/Concepts/TechnicalRequirements/Architecture/TechnicalOverview.md +++ b/docu/Concepts/TechnicalRequirements/Architecture/TechnicalOverview.md @@ -15,7 +15,7 @@ This document describes the technical overview for the Gradido infrastructur. Be ![CommunityServerAPI](../image/CommunityServerAPI.png) -### Database Skeema +### Database Skeema (outdated) ![CommunityDBSkeema](../image/CommunityDBSkeema.png) diff --git a/docu/Gradido-Admin.epgz b/docu/Gradido-Admin.epgz new file mode 100644 index 000000000..9c00dc445 Binary files /dev/null and b/docu/Gradido-Admin.epgz differ diff --git a/docu/create-coins-as-admin.md b/docu/create-coins-as-admin.md new file mode 100644 index 000000000..6a95df119 --- /dev/null +++ b/docu/create-coins-as-admin.md @@ -0,0 +1,27 @@ +### User creation +A user needs to be created on the login_server we do this when we create a User in the client https://$community_domain/vue/register. + +### Admin user +To set a User admin we need the following SQL query on the gradido_login database: +``` +INSERT INTO user_roles (id, user_id, role_id) VALUES (NULL, '1', '1'); +``` +user_id has to be found in users +Now when we login in on https://$community_domain/account/ we can create coins but we will be restricted cause we can't sign the creations. + +### Signation account +At first we need to enable the server user account creation with uncommenting line: 19 in +community_server/src/Controller/ServerUsersController.php +```php +$this->Auth->allow(['add', 'edit']); +``` +This enable us to use this action without being logged in. +To add a signation account we need to go on the following url: http://$community_domain/server-users/add + +### Coin creation process +The coin creation for work is done in the following url: http://$community_domain/transaction-creations/create-multi +Where we can create coins for a number of as many users as we want excepted for our self. +Furthermore we must sign the transactions we created. Normally after clicking on the left button (Transaktion abschließen) we should be automatically forwarded to http://$community_domain/account/checkTransactions where we can do this. +If not this page can also be reached by clicking on the shield-icon with the hook in it on the Dashboard, which is only shown if at least one transaction is waiting for signing. + +For debug purposes you can check the `pending_tasks` table, which is used to store the transactions which are not signed yet or had errors. \ No newline at end of file diff --git a/docu/graphics/gradido_admin.png b/docu/graphics/gradido_admin.png new file mode 100644 index 000000000..855cf903e Binary files /dev/null and b/docu/graphics/gradido_admin.png differ diff --git a/docu/graphics/userdetails.png b/docu/graphics/userdetails.png new file mode 100644 index 000000000..b31ff3e63 Binary files /dev/null and b/docu/graphics/userdetails.png differ diff --git a/docu/presentation/adminarea-old-new.pdf b/docu/presentation/adminarea-old-new.pdf new file mode 100644 index 000000000..3fda700ec Binary files /dev/null and b/docu/presentation/adminarea-old-new.pdf differ diff --git a/frontend/package.json b/frontend/package.json index b5c7868b7..e50c5fe89 100755 --- a/frontend/package.json +++ b/frontend/package.json @@ -27,7 +27,6 @@ "babel-preset-vue": "^2.0.2", "bootstrap": "4.3.1", "bootstrap-vue": "^2.5.0", - "chart.js": "^2.9.3", "d3": "^5.7.0", "datamaps": "^0.5.9", "date-fns": "^1.30.1", @@ -64,7 +63,6 @@ "vue": "^2.6.11", "vue-apollo": "^3.0.7", "vue-bootstrap-typeahead": "^0.2.6", - "vue-chartjs": "^3.5.0", "vue-cli-plugin-i18n": "^1.0.1", "vue-clickaway": "^2.2.2", "vue-clipboard2": "^0.3.0", diff --git a/frontend/src/components/DecayInformation.vue b/frontend/src/components/DecayInformation.vue index 0b7f3d863..28af9b2b4 100644 --- a/frontend/src/components/DecayInformation.vue +++ b/frontend/src/components/DecayInformation.vue @@ -1,12 +1,7 @@ diff --git a/frontend/src/components/Status.spec.js b/frontend/src/components/Status.spec.js new file mode 100644 index 000000000..30dab4345 --- /dev/null +++ b/frontend/src/components/Status.spec.js @@ -0,0 +1,45 @@ +import { mount } from '@vue/test-utils' +import Status from './Status' + +const localVue = global.localVue + +describe('Status', () => { + let wrapper + + const mocks = { + $n: jest.fn((n) => n), + } + + const propsData = { + balance: 1234, + statusText: 'GDD', + } + + const Wrapper = () => { + return mount(Status, { localVue, mocks, propsData }) + } + + describe('mount', () => { + beforeEach(() => { + wrapper = Wrapper() + }) + + describe('balance is pending', () => { + it('it displays an en-dash', () => { + expect(wrapper.find('div.gdd-status-div').text()).toEqual('— GDD') + }) + }) + + describe('balance is loaded', () => { + beforeEach(() => { + wrapper.setProps({ + pending: false, + }) + }) + + it('it displays the ammount of GDD', () => { + expect(wrapper.find('div.gdd-status-div').text()).toEqual('1234 GDD') + }) + }) + }) +}) diff --git a/frontend/src/components/Status.vue b/frontend/src/components/Status.vue new file mode 100644 index 000000000..7900763f7 --- /dev/null +++ b/frontend/src/components/Status.vue @@ -0,0 +1,24 @@ + + + diff --git a/frontend/src/components/Transaction.spec.js b/frontend/src/components/Transaction.spec.js index 43dc44782..aaad023e0 100644 --- a/frontend/src/components/Transaction.spec.js +++ b/frontend/src/components/Transaction.spec.js @@ -1,8 +1,11 @@ import { mount } from '@vue/test-utils' import Transaction from './Transaction' +import Vue from 'vue' const localVue = global.localVue +const consoleErrorMock = jest.fn() + describe('Transaction', () => { let wrapper @@ -27,5 +30,206 @@ describe('Transaction', () => { it('renders the component', () => { expect(wrapper.find('div.gdt-transaction-list-item').exists()).toBeTruthy() }) + + it('has a collapse button', () => { + expect(wrapper.find('button[type="button"].btn-secondary').text()).toBe('i') + }) + + describe('no valid GDT entry type', () => { + beforeEach(async () => { + // disable throwing Errors on warnings to catch the warning + Vue.config.warnHandler = (w) => {} + // eslint-disable-next-line no-console + console.error = consoleErrorMock + await wrapper.setProps({ gdtEntryType: 'NOT_VALID' }) + }) + + it('throws an error', () => { + expect(consoleErrorMock).toBeCalledWith( + expect.objectContaining({ message: 'no lines for this type: NOT_VALID' }), + ) + }) + }) + + describe('default entry type FORM', () => { + beforeEach(async () => { + await wrapper.setProps({ + amount: 100, + date: '2021-05-02T17:20:11+00:00', + comment: 'This is a comment', + factor: 17, + gdt: 1700, + id: 42, + }) + }) + + it('has the heart icon', () => { + expect(wrapper.find('svg.bi-heart').exists()).toBeTruthy() + }) + + it('has the description gdt.contribution', () => { + expect(wrapper.findAll('div.row').at(0).text()).toContain('gdt.contribution') + }) + + it('renders the amount of euros', () => { + expect(wrapper.findAll('div.row').at(0).text()).toContain('100 €') + }) + + it('renders the amount of GDT', () => { + expect(wrapper.findAll('div.row').at(1).text()).toContain('1700 GDT') + }) + + it('renders the comment message', () => { + expect(wrapper.findAll('div.row').at(2).text()).toContain('This is a comment') + }) + + it('renders the date', () => { + expect(wrapper.findAll('div.row').at(3).text()).toContain('Sun May 02 2021') + }) + + it('does not show the collapse by default', () => { + expect(wrapper.find('div#gdt-collapse-42').isVisible()).toBeFalsy() + }) + + describe('without comment', () => { + it('does not render the message row', async () => { + await wrapper.setProps({ comment: undefined }) + expect(wrapper.findAll('div.row').at(2).text()).toContain('form.date') + }) + }) + /* how to open the collapse ????? + describe('collapse is open', () => { + beforeEach(async () => { + //console.log(wrapper.html()) + await wrapper.find('div#gdt-collapse-42').trigger('click') + await wrapper.vm.$nextTick() + await flushPromises() + await wrapper.vm.$nextTick() + await flushPromises() + //console.log(wrapper.find('[enteractiveclass="collapsing"]').html()) + }) + + it('shows the collapse', () => { + //console.log(wrapper.html()) + expect(wrapper.find('div#gdt-collapse-42').isVisible()).toBeTruthy() + }) + }) + */ + }) + + describe('GdtEntryType.CVS', () => { + it('behaves as default FORM', async () => { + await wrapper.setProps({ gdtEntryType: 'CVS' }) + expect(wrapper.find('svg.bi-heart').exists()).toBeTruthy() + }) + }) + + describe('GdtEntryType.ELOPAGE', () => { + it('behaves as default FORM', async () => { + await wrapper.setProps({ gdtEntryType: 'ELOPAGE' }) + expect(wrapper.find('svg.bi-heart').exists()).toBeTruthy() + }) + }) + + describe('GdtEntryType.DIGISTORE', () => { + it('behaves as default FORM', async () => { + await wrapper.setProps({ gdtEntryType: 'DIGISTORE' }) + expect(wrapper.find('svg.bi-heart').exists()).toBeTruthy() + }) + }) + + describe('GdtEntryType.CVS2', () => { + it('behaves as default FORM', async () => { + await wrapper.setProps({ gdtEntryType: 'CVS2' }) + expect(wrapper.find('svg.bi-heart').exists()).toBeTruthy() + }) + }) + + describe('GdtEntryType.ELOPAGE_PUBLISHER', () => { + beforeEach(async () => { + await wrapper.setProps({ + amount: 365.67, + date: '2020-04-10T13:28:00+00:00', + comment: 'This is a comment', + gdtEntryType: 'ELOPAGE_PUBLISHER', + factor: 22, + gdt: 967.65, + id: 42, + }) + }) + + it('has the person-check icon', () => { + expect(wrapper.find('svg.bi-person-check').exists()).toBeTruthy() + }) + + it('has the description gdt.recruited-member', () => { + expect(wrapper.findAll('div.row').at(0).text()).toContain('gdt.recruited-member') + }) + + it('renders the percentage', () => { + expect(wrapper.findAll('div.row').at(0).text()).toContain('5%') + }) + + it('renders the amount of GDT', () => { + expect(wrapper.findAll('div.row').at(1).text()).toContain('365.67 GDT') + }) + + it('renders the comment message', () => { + expect(wrapper.findAll('div.row').at(2).text()).toContain('This is a comment') + }) + + it('renders the date', () => { + expect(wrapper.findAll('div.row').at(3).text()).toContain('Fri Apr 10 2020') + }) + + it('does not show the collapse by default', () => { + expect(wrapper.find('div#gdt-collapse-42').isVisible()).toBeFalsy() + }) + + describe('without comment', () => { + it('does not render the message row', async () => { + await wrapper.setProps({ comment: undefined }) + expect(wrapper.findAll('div.row').at(2).text()).toContain('form.date') + }) + }) + }) + + describe('GdtEntryType.GLOBAL_MODIFICATOR', () => { + beforeEach(async () => { + await wrapper.setProps({ + amount: 123.45, + date: '2020-03-12T13:28:00+00:00', + comment: 'This is a comment', + gdtEntryType: 'GLOBAL_MODIFICATOR', + factor: 19, + gdt: 61.23, + id: 42, + }) + }) + + it('has the gift icon', () => { + expect(wrapper.find('svg.bi-gift').exists()).toBeTruthy() + }) + + it('has the description gdt.gdt-received', () => { + expect(wrapper.findAll('div.row').at(0).text()).toContain('gdt.gdt-received') + }) + + it('renders the comment', () => { + expect(wrapper.findAll('div.row').at(0).text()).toContain('This is a comment') + }) + + it('renders the amount of GDT', () => { + expect(wrapper.findAll('div.row').at(1).text()).toContain('61.23 GDT') + }) + + it('renders the date', () => { + expect(wrapper.findAll('div.row').at(2).text()).toContain('Thu Mar 12 2020') + }) + + it('does not show the collapse by default', () => { + expect(wrapper.find('div#gdt-collapse-42').isVisible()).toBeFalsy() + }) + }) }) }) diff --git a/frontend/src/components/Transaction.vue b/frontend/src/components/Transaction.vue index cc027306b..f1deca565 100644 --- a/frontend/src/components/Transaction.vue +++ b/frontend/src/components/Transaction.vue @@ -1,13 +1,10 @@