Merge remote-tracking branch 'origin/master' into 2913-feature-mirgate-transactions-table-for-x-community-sendcoins

This commit is contained in:
Claus-Peter Hübner 2023-04-03 21:35:55 +02:00
commit 1380b5a94a
25 changed files with 180 additions and 186 deletions

View File

@ -5,7 +5,7 @@ module.exports = {
node: true,
},
parser: '@typescript-eslint/parser',
plugins: ['prettier', '@typescript-eslint', 'type-graphql', 'jest', 'import'],
plugins: ['prettier', '@typescript-eslint', 'type-graphql', 'jest', 'import', 'n'],
extends: [
'standard',
'eslint:recommended',
@ -101,6 +101,45 @@ module.exports = {
},
],
'import/prefer-default-export': 'off', // TODO
// n
'n/handle-callback-err': 'error',
'n/no-callback-literal': 'error',
'n/no-exports-assign': 'error',
'n/no-extraneous-import': 'error',
'n/no-extraneous-require': 'error',
'n/no-hide-core-modules': 'error',
'n/no-missing-import': 'off', // not compatible with typescript
'n/no-missing-require': 'error',
'n/no-new-require': 'error',
'n/no-path-concat': 'error',
'n/no-process-exit': 'error',
'n/no-unpublished-bin': 'error',
'n/no-unpublished-import': 'off', // TODO need to exclude seeds
'n/no-unpublished-require': 'error',
'n/no-unsupported-features': ['error', { ignores: ['modules'] }],
'n/no-unsupported-features/es-builtins': 'error',
'n/no-unsupported-features/es-syntax': 'error',
'n/no-unsupported-features/node-builtins': 'error',
'n/process-exit-as-throw': 'error',
'n/shebang': 'error',
'n/callback-return': 'error',
'n/exports-style': 'error',
'n/file-extension-in-import': 'off',
'n/global-require': 'error',
'n/no-mixed-requires': 'error',
'n/no-process-env': 'error',
'n/no-restricted-import': 'error',
'n/no-restricted-require': 'error',
'n/no-sync': 'error',
'n/prefer-global/buffer': 'error',
'n/prefer-global/console': 'error',
'n/prefer-global/process': 'error',
'n/prefer-global/text-decoder': 'error',
'n/prefer-global/text-encoder': 'error',
'n/prefer-global/url': 'error',
'n/prefer-global/url-search-params': 'error',
'n/prefer-promises/dns': 'error',
'n/prefer-promises/fs': 'error',
},
overrides: [
// only for ts files

View File

@ -22,10 +22,12 @@ module.exports = {
'@repository/(.*)': '<rootDir>/src/typeorm/repository/$1',
'@test/(.*)': '<rootDir>/test/$1',
'@entity/(.*)':
// eslint-disable-next-line n/no-process-env
process.env.NODE_ENV === 'development'
? '<rootDir>/../database/entity/$1'
: '<rootDir>/../database/build/entity/$1',
'@dbTools/(.*)':
// eslint-disable-next-line n/no-process-env
process.env.NODE_ENV === 'development'
? '<rootDir>/../database/src/$1'
: '<rootDir>/../database/build/src/$1',

View File

@ -65,6 +65,7 @@
"eslint-import-resolver-typescript": "^3.5.3",
"eslint-plugin-import": "^2.27.5",
"eslint-plugin-jest": "^27.2.1",
"eslint-plugin-n": "^15.6.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-promise": "^5.1.0",
@ -84,5 +85,8 @@
"ignore": [
"**/*.test.ts"
]
},
"engines": {
"node": ">=14"
}
}

View File

@ -1,4 +1,5 @@
// ATTENTION: DO NOT PUT ANY SECRETS IN HERE (or the .env)
/* eslint-disable n/no-process-env */
import { Decimal } from 'decimal.js-light'
import dotenv from 'dotenv'

View File

@ -1,6 +1,4 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
// config
import CONFIG from './config'
import { startValidateCommunities } from './federation/validateCommunities'
import createServer from './server/createServer'
@ -22,5 +20,5 @@ async function main() {
main().catch((e) => {
// eslint-disable-next-line no-console
console.error(e)
process.exit(1)
throw e
})

View File

@ -28,6 +28,7 @@ export const klicktippNewsletterStateMiddleware: MiddlewareFn = async (
{ root, args, context, info },
next,
) => {
// eslint-disable-next-line n/callback-return
const result = await next()
let klickTipp = new KlickTipp({ status: 'Unsubscribed' })
if (CONFIG.KLICKTIPP) {

View File

@ -61,6 +61,7 @@ ${JSON.stringify(requestContext.response.errors, null, 2)}`)
}
const plugins =
// eslint-disable-next-line n/no-process-env
process.env.NODE_ENV === 'development' ? [setHeadersPlugin] : [setHeadersPlugin, logPlugin]
export default plugins

View File

@ -6,7 +6,6 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { initialize } from '@dbTools/helpers'
import { entities } from '@entity/index'
import { createTestClient } from 'apollo-server-testing'
@ -40,7 +39,6 @@ export const testEnvironment = async (testLogger: any = logger, testI18n: any =
const testClient = createTestClient(server.apollo)
const mutate = testClient.mutate
const query = testClient.query
await initialize()
return { mutate, query, con }
}

View File

@ -1998,6 +1998,13 @@ buffer@^6.0.3:
base64-js "^1.3.1"
ieee754 "^1.2.1"
builtins@^5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/builtins/-/builtins-5.0.1.tgz#87f6db9ab0458be728564fa81d876d8d74552fa9"
integrity sha512-qwVpFEHNfhYJIzNRBvd2C1kyo6jz3ZSMPyyuR47OPdiKWlbYnZNyDWuyR175qDnAJLiCo5fBBqPb3RiXgWlkOQ==
dependencies:
semver "^7.0.0"
busboy@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.3.1.tgz#170899274c5bf38aae27d5c62b71268cd585fd1b"
@ -2937,6 +2944,14 @@ eslint-plugin-es@^3.0.0:
eslint-utils "^2.0.0"
regexpp "^3.0.0"
eslint-plugin-es@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/eslint-plugin-es/-/eslint-plugin-es-4.1.0.tgz#f0822f0c18a535a97c3e714e89f88586a7641ec9"
integrity sha512-GILhQTnjYE2WorX5Jyi5i4dz5ALWxBIdQECVQavL6s7cI76IZTDWleTHkxz/QT3kvcs2QlGHvKLYsSlPOlPXnQ==
dependencies:
eslint-utils "^2.0.0"
regexpp "^3.0.0"
eslint-plugin-import@^2.27.5:
version "2.27.5"
resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz#876a6d03f52608a3e5bb439c2550588e51dd6c65"
@ -2965,6 +2980,20 @@ eslint-plugin-jest@^27.2.1:
dependencies:
"@typescript-eslint/utils" "^5.10.0"
eslint-plugin-n@^15.6.1:
version "15.6.1"
resolved "https://registry.yarnpkg.com/eslint-plugin-n/-/eslint-plugin-n-15.6.1.tgz#f7e77f24abb92a550115cf11e29695da122c398c"
integrity sha512-R9xw9OtCRxxaxaszTQmQAlPgM+RdGjaL1akWuY/Fv9fRAi8Wj4CUKc6iYVG8QNRjRuo8/BqVYIpfqberJUEacA==
dependencies:
builtins "^5.0.1"
eslint-plugin-es "^4.1.0"
eslint-utils "^3.0.0"
ignore "^5.1.1"
is-core-module "^2.11.0"
minimatch "^3.1.2"
resolve "^1.22.1"
semver "^7.3.8"
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"
@ -6300,7 +6329,7 @@ semver@^6.0.0, semver@^6.1.0, semver@^6.2.0, semver@^6.3.0:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
semver@^7.3.7:
semver@^7.0.0, semver@^7.3.7, semver@^7.3.8:
version "7.3.8"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798"
integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==

View File

@ -4,5 +4,3 @@ DB_USER=root
DB_PASSWORD=
DB_DATABASE=gradido_community
MIGRATIONS_TABLE=migrations
TYPEORM_SEEDING_FACTORIES=src/factories/**/*{.ts,.js}

View File

@ -6,5 +6,3 @@ DB_USER=$DB_USER
DB_PASSWORD=$DB_PASSWORD
DB_DATABASE=gradido_community
MIGRATIONS_TABLE=migrations
TYPEORM_SEEDING_FACTORIES=src/factories/**/*{.ts,.js}

View File

@ -1,15 +0,0 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const CONFIG = require('./src/config')
module.export = {
name: 'default',
type: 'mysql',
host: CONFIG.DB_HOST,
port: CONFIG.DB_PORT,
username: CONFIG.DB_USER,
password: CONFIG.DB_PASSWORD,
database: CONFIG.DB_DATABASE,
seeds: ['src/seeds/**/*{.ts,.js}'],
factories: ['src/factories/**/*{.ts,.js}'],
}

View File

@ -1,34 +0,0 @@
import CONFIG from './config'
import { createPool, PoolConfig } from 'mysql'
import { Migration } from 'ts-mysql-migrate'
import path from 'path'
const poolConfig: PoolConfig = {
host: CONFIG.DB_HOST,
port: CONFIG.DB_PORT,
user: CONFIG.DB_USER,
password: CONFIG.DB_PASSWORD,
database: CONFIG.DB_DATABASE,
}
// Pool?
const pool = createPool(poolConfig)
// Create & Initialize Migrations
const migration = new Migration({
conn: pool,
tableName: CONFIG.MIGRATIONS_TABLE,
silent: true,
dir: path.join(__dirname, '..', 'migrations'),
})
const initialize = async (): Promise<void> => {
await migration.initialize()
}
const resetDB = async (closePool = false): Promise<void> => {
await migration.reset() // use for resetting database
if (closePool) pool.end()
}
export { resetDB, pool, migration, initialize }

View File

@ -1,18 +1,29 @@
import 'reflect-metadata'
import prepare from './prepare'
import connection from './typeorm/connection'
import { resetDB, pool, migration } from './helpers'
import { createDatabase } from './prepare'
import CONFIG from './config'
import { createPool } from 'mysql'
import { Migration } from 'ts-mysql-migrate'
import path from 'path'
const run = async (command: string) => {
// Database actions not supported by our migration library
await prepare()
// Database connection for TypeORM
const con = await connection()
if (!con || !con.isConnected) {
throw new Error(`Couldn't open connection to database`)
}
await createDatabase()
// Initialize Migrations
const pool = createPool({
host: CONFIG.DB_HOST,
port: CONFIG.DB_PORT,
user: CONFIG.DB_USER,
password: CONFIG.DB_PASSWORD,
database: CONFIG.DB_DATABASE,
})
const migration = new Migration({
conn: pool,
tableName: CONFIG.MIGRATIONS_TABLE,
silent: true,
dir: path.join(__dirname, '..', 'migrations'),
})
await migration.initialize()
// Execute command
@ -25,14 +36,13 @@ const run = async (command: string) => {
break
case 'reset':
// TODO protect from production
await resetDB() // use for resetting database
await migration.reset()
break
default:
throw new Error(`Unsupported command ${command}`)
}
// Terminate connections gracefully
await con.close()
pool.end()
}

View File

@ -1,12 +0,0 @@
import Decimal from 'decimal.js-light'
export interface TransactionContext {
typeId: number
userId: number
balance: Decimal
balanceDate: Date
amount: Decimal
memo: string
creationDate?: Date
sendReceiverUserId?: number
}

View File

@ -1,26 +0,0 @@
export interface UserContext {
pubKey?: Buffer
email?: string
firstName?: string
lastName?: string
deletedAt?: Date
password?: BigInt
privKey?: Buffer
emailHash?: Buffer
createdAt?: Date
emailChecked?: boolean
language?: string
publisherId?: number
passphrase?: string
}
export interface ServerUserContext {
username?: string
password?: string
email?: string
role?: string
activated?: number
lastLogin?: Date
created?: Date
modified?: Date
}

View File

@ -1,32 +0,0 @@
import Decimal from 'decimal.js-light'
export interface UserInterface {
// from user
email?: string
firstName?: string
lastName?: string
password?: BigInt
pubKey?: Buffer
privKey?: Buffer
emailHash?: Buffer
createdAt?: Date
emailChecked?: boolean
language?: string
deletedAt?: Date
publisherId?: number
passphrase?: string
// from server user
serverUserPassword?: string
role?: string
activated?: number
lastLogin?: Date
modified?: Date
// flag for admin
isAdmin?: boolean
// flag for balance (creation of 1000 GDD)
addBalance?: boolean
// balance
recordDate?: Date
creationDate?: Date
amount?: Decimal
}

View File

@ -1,15 +1,8 @@
/* PREPARE SCRIPT
*
* This file ensures operations our migration library
* can not take care of are done.
* This applies to all Database Operations like
* creating, deleting, renaming Databases.
*/
import { createConnection } from 'mysql2/promise'
import { createConnection, RowDataPacket } from 'mysql2/promise'
import CONFIG from './config'
export default async (): Promise<void> => {
export const createDatabase = async (): Promise<void> => {
const con = await createConnection({
host: CONFIG.DB_HOST,
port: CONFIG.DB_PORT,
@ -25,6 +18,8 @@ export default async (): Promise<void> => {
DEFAULT CHARACTER SET utf8mb4
DEFAULT COLLATE utf8mb4_unicode_ci;`)
/* LEGACY CODE
import { RowDataPacket } from 'mysql2/promise'
// Check if old migration table is present, delete if needed
const [rows] = await con.query(`SHOW TABLES FROM \`${CONFIG.DB_DATABASE}\` LIKE 'migrations';`)
if ((<RowDataPacket>rows).length > 0) {
@ -37,6 +32,7 @@ export default async (): Promise<void> => {
console.log('Found and dropped old migrations table')
}
}
*/
await con.end()
}

View File

@ -1,27 +0,0 @@
import { createConnection, Connection } from 'typeorm'
import CONFIG from '../config'
import { entities } from '../../entity/index'
const connection = async (): Promise<Connection | null> => {
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

View File

@ -4,7 +4,6 @@
import CONFIG from '@/config'
import connection from '@/typeorm/connection'
import { checkDBVersion } from '@/typeorm/DBVersion'
import { initialize } from '@dbTools/helpers'
import { entities } from '@entity/index'
import { logger } from './testSetup'
@ -42,7 +41,6 @@ export const testEnvironment = async () => {
logger.fatal('Fatal: Database Version incorrect')
throw new Error('Fatal: Database Version incorrect')
}
await initialize()
return { con }
}

View File

@ -6,12 +6,15 @@ const localVue = global.localVue
const propsData = {
link: '',
}
const mocks = {
$t: jest.fn((t) => t),
}
describe('FigureQrCode', () => {
let wrapper
const Wrapper = () => {
return mount(FigureQrCode, { localVue, propsData })
return mount(FigureQrCode, { localVue, mocks, propsData })
}
describe('mount', () => {
@ -19,12 +22,55 @@ describe('FigureQrCode', () => {
wrapper = Wrapper()
})
it('renders the Div Element ".figure-qr-code"', () => {
expect(wrapper.find('div.figure-qr-code').exists()).toBeTruthy()
afterEach(() => {
jest.clearAllMocks()
})
it('renders the Div Element "q-r-canvas"', () => {
expect(wrapper.find('q-r-canvas'))
it('has options filled', () => {
expect(wrapper.vm.options).toEqual({
cellSize: 8,
correctLevel: 'H',
data: '',
})
})
it('renders the Div Element ".figure-qr-code"', () => {
expect(wrapper.find('div.figure-qr-code').exists()).toBe(true)
})
it('renders the Div Element "qrbox"', () => {
expect(wrapper.find('div.qrbox').exists()).toBe(true)
})
it('renders the Canvas Element "#qrcanvas"', () => {
const canvas = wrapper.find('#qrcanvas')
expect(canvas.exists()).toBe(true)
const canvasEl = canvas.element
const canvasWidth = canvasEl.width
const canvasHeight = canvasEl.height
expect(canvasWidth).toBeGreaterThan(0)
expect(canvasHeight).toBeGreaterThan(0)
const canvasContext = canvasEl.toDataURL('image/png')
expect(canvasContext).not.toBeNull()
})
it('renders the A Element "#download"', () => {
const downloadLink = wrapper.find('#download')
expect(downloadLink.exists()).toBe(true)
})
describe('Download QR-Code link', () => {
beforeEach(() => {
const downloadLink = wrapper.find('#download')
downloadLink.trigger('click')
})
it('click the A Element "#download" set an href', () => {
expect(wrapper.find('#download').attributes('href')).toEqual('data:image/png;base64,00')
})
})
})
})

View File

@ -1,7 +1,18 @@
<template>
<div class="figure-qr-code">
<div class="qrbox">
<q-r-canvas :options="options" class="canvas" />
<div>
<q-r-canvas :options="options" class="canvas mb-3" id="qrcanvas" ref="canvas" />
</div>
<a
id="download"
ref="download"
download="GradidoLinkQRCode.png"
href=""
@click="downloadImg(this)"
>
{{ $t('download') }}
</a>
</div>
</div>
</template>
@ -37,6 +48,13 @@ export default {
}
}
},
methods: {
downloadImg() {
const canvas = this.$refs.canvas.$el
const image = canvas.toDataURL('image/png')
this.$refs.download.href = image
},
},
}
</script>
<style scoped>

View File

@ -100,6 +100,7 @@
}
},
"delete": "Löschen",
"download": "Herunterladen",
"edit": "bearbeiten",
"em-dash": "—",
"error": {

View File

@ -100,6 +100,7 @@
}
},
"delete": "Delete",
"download": "Download",
"edit": "edit",
"em-dash": "—",
"error": {

View File

@ -88,6 +88,7 @@
}
},
"delete": "Supprimer",
"download": "Télécharger",
"edit": "modifier",
"em-dash": "—",
"error": {