Merge branch 'master' into federation-remove-duplicate-db-query

This commit is contained in:
Ulf Gebhardt 2023-06-09 13:09:31 +02:00 committed by GitHub
commit ad3aad8695
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 114 additions and 219 deletions

View File

@ -58,7 +58,7 @@ module.exports = {
'import/no-dynamic-require': 'error',
'import/no-internal-modules': 'off',
'import/no-relative-packages': 'error',
'import/no-relative-parent-imports': ['error', { ignore: ['@/*'] }],
'import/no-relative-parent-imports': ['error', { ignore: ['@/*', 'random-bigint'] }],
'import/no-self-import': 'error',
'import/no-unresolved': 'error',
'import/no-useless-path-segments': 'error',

View File

@ -0,0 +1,5 @@
/* eslint-disable @typescript-eslint/ban-types */
declare module 'random-bigint' {
function random(bits: number, cb?: (err: Error, num: BigInt) => void): BigInt
export = random
}

View File

@ -70,13 +70,13 @@ import { communityDbUser } from '@/util/communityUser'
import { hasElopageBuys } from '@/util/hasElopageBuys'
import { getTimeDurationObject, printTimeDuration } from '@/util/time'
import random from 'random-bigint'
import { FULL_CREATION_AVAILABLE } from './const/const'
import { getUserCreations } from './util/creations'
import { findUserByIdentifier } from './util/findUserByIdentifier'
import { validateAlias } from './util/validateAlias'
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-commonjs
const random = require('random-bigint')
// eslint-disable-next-line @typescript-eslint/no-var-requires, import/no-commonjs
const sodium = require('sodium-native')

View File

@ -66,8 +66,6 @@ export async function upgrade(queryFn: (query: string, values?: any[]) => Promis
)
}
/* eslint-disable @typescript-eslint/no-empty-function */
/* eslint-disable-next-line @typescript-eslint/no-unused-vars */
export async function downgrade(queryFn: (query: string, values?: any[]) => Promise<Array<any>>) {
await queryFn('ALTER TABLE `transactions` DROP COLUMN `user_gradido_id`;')
await queryFn('ALTER TABLE `transactions` DROP COLUMN `user_name`;')

View File

@ -68,7 +68,7 @@ FEDERATION_COMMUNITY_API_PORT=5000
FEDERATION_CONFIG_VERSION=v1.2023-01-09
# comma separated list of api-versions, which cause starting several federation modules
FEDERATION_COMMUNITY_APIS=1_0,1_1,2_0
FEDERATION_COMMUNITY_APIS=1_0,1_1
# database
DATABASE_CONFIG_VERSION=v1.2022-03-18

View File

@ -8,11 +8,6 @@ import { Community as DbCommunity } from '@entity/Community'
import { v4 as uuidv4 } from 'uuid'
const KEY_SECRET_SEEDBYTES = 32
const getSeed = (): Buffer | null => {
return CONFIG.FEDERATION_DHT_SEED
? Buffer.alloc(KEY_SECRET_SEEDBYTES, CONFIG.FEDERATION_DHT_SEED)
: null
}
const POLLTIME = 20000
const SUCCESSTIME = 120000
@ -24,7 +19,7 @@ enum ApiVersionType {
V1_1 = '1_1',
V2_0 = '2_0',
}
export type CommunityApi = {
type CommunityApi = {
api: string
url: string
}
@ -32,7 +27,12 @@ export type CommunityApi = {
export const startDHT = async (topic: string): Promise<void> => {
try {
const TOPIC = DHT.hash(Buffer.from(topic))
const keyPair = DHT.keyPair(getSeed())
// uses a config defined seed or null, which will generate a random seed for the key pair
const keyPair = DHT.keyPair(
CONFIG.FEDERATION_DHT_SEED
? Buffer.alloc(KEY_SECRET_SEEDBYTES, CONFIG.FEDERATION_DHT_SEED)
: null,
)
const pubKeyString = keyPair.publicKey.toString('hex')
logger.info(`keyPairDHT: publicKey=${pubKeyString}`)
logger.debug(`keyPairDHT: secretKey=${keyPair.secretKey.toString('hex')}`)
@ -243,14 +243,11 @@ async function writeHomeCommunityEntry(pubKey: string): Promise<void> {
}
const newCommunityUuid = async (): Promise<string> => {
let uuid: string
let countIds: number
do {
uuid = uuidv4()
countIds = await DbCommunity.count({ where: { communityUuid: uuid } })
if (countIds > 0) {
logger.info('CommunityUuid creation conflict...')
while (true) {
const communityUuid = uuidv4()
if ((await DbCommunity.count({ where: { communityUuid } })) === 0) {
return communityUuid
}
} while (countIds > 0)
return uuid
logger.info('CommunityUuid creation conflict...', communityUuid)
}
}

View File

@ -3,12 +3,15 @@
import { createTestClient } from 'apollo-server-testing'
import createServer from '@/server/createServer'
import { FederatedCommunity as DbFederatedCommunity } from '@entity/FederatedCommunity'
import CONFIG from '@/config'
let query: any
// to do: We need a setup for the tests that closes the connection
let con: any
CONFIG.FEDERATION_API = '1_0'
beforeAll(async () => {
const server = await createServer()
con = server.con

View File

@ -1,41 +0,0 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { createTestClient } from 'apollo-server-testing'
import createServer from '@/server/createServer'
let query: any
// to do: We need a setup for the tests that closes the connection
let con: any
beforeAll(async () => {
const server = await createServer()
con = server.con
query = createTestClient(server.apollo).query
})
afterAll(async () => {
await con.close()
})
describe('TestResolver', () => {
const getTestQuery = `
query {
test {
api
}
}
`
describe('getTestApi', () => {
it('returns 1_0', async () => {
await expect(query({ query: getTestQuery })).resolves.toMatchObject({
data: {
test: {
api: '1_0',
},
},
})
})
})
})

View File

@ -1,14 +0,0 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { Query, Resolver } from 'type-graphql'
import { federationLogger as logger } from '@/server/logger'
import { GetTestApiResult } from '../../GetTestApiResult'
@Resolver()
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export class TestResolver {
@Query(() => GetTestApiResult)
async test(): Promise<GetTestApiResult> {
logger.info(`test api 1_0`)
return new GetTestApiResult('1_0')
}
}

View File

@ -0,0 +1,56 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { createTestClient } from 'apollo-server-testing'
import createServer from '@/server/createServer'
import { FederatedCommunity as DbFederatedCommunity } from '@entity/FederatedCommunity'
import CONFIG from '@/config'
let query: any
// to do: We need a setup for the tests that closes the connection
let con: any
CONFIG.FEDERATION_API = '1_1'
beforeAll(async () => {
const server = await createServer()
con = server.con
query = createTestClient(server.apollo).query
DbFederatedCommunity.clear()
})
afterAll(async () => {
await con.close()
})
describe('PublicKeyResolver', () => {
const getPublicKeyQuery = `
query {
getPublicKey
{
publicKey
}
}
`
describe('getPublicKey', () => {
beforeEach(async () => {
const homeCom = new DbFederatedCommunity()
homeCom.foreign = false
homeCom.apiVersion = '1_0'
homeCom.endPoint = 'endpoint-url'
homeCom.publicKey = Buffer.from('homeCommunity-publicKey')
await DbFederatedCommunity.insert(homeCom)
})
it('returns homeCommunity-publicKey', async () => {
await expect(query({ query: getPublicKeyQuery })).resolves.toMatchObject({
data: {
getPublicKey: {
publicKey: expect.stringMatching('homeCommunity-publicKey'),
},
},
})
})
})
})

View File

@ -0,0 +1,8 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { Resolver } from 'type-graphql'
// eslint-disable-next-line camelcase
import { PublicKeyResolver as PublicKeyResolver_1_0 } from '../../1_0/resolver/PublicKeyResolver'
@Resolver()
// eslint-disable-next-line camelcase, @typescript-eslint/no-unused-vars
export class PublicKeyResolver extends PublicKeyResolver_1_0 {}

View File

@ -1,44 +0,0 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { createTestClient } from 'apollo-server-testing'
import createServer from '@/server/createServer'
import CONFIG from '@/config'
CONFIG.FEDERATION_API = '1_1'
let query: any
// to do: We need a setup for the tests that closes the connection
let con: any
beforeAll(async () => {
const server = await createServer()
con = server.con
query = createTestClient(server.apollo).query
})
afterAll(async () => {
await con.close()
})
describe('TestResolver', () => {
const getTestQuery = `
query {
test {
api
}
}
`
describe('getTestApi', () => {
it('returns 1_1', async () => {
await expect(query({ query: getTestQuery })).resolves.toMatchObject({
data: {
test: {
api: '1_1',
},
},
})
})
})
})

View File

@ -1,14 +0,0 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { Query, Resolver } from 'type-graphql'
import { federationLogger as logger } from '@/server/logger'
import { GetTestApiResult } from '../../GetTestApiResult'
@Resolver()
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export class TestResolver {
@Query(() => GetTestApiResult)
async test(): Promise<GetTestApiResult> {
logger.info(`test api 1_1`)
return new GetTestApiResult('1_1')
}
}

View File

@ -1,44 +0,0 @@
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { createTestClient } from 'apollo-server-testing'
import createServer from '@/server/createServer'
import CONFIG from '@/config'
CONFIG.FEDERATION_API = '2_0'
let query: any
// to do: We need a setup for the tests that closes the connection
let con: any
beforeAll(async () => {
const server = await createServer()
con = server.con
query = createTestClient(server.apollo).query
})
afterAll(async () => {
await con.close()
})
describe('TestResolver', () => {
const getTestQuery = `
query {
test {
api
}
}
`
describe('getTestApi', () => {
it('returns 2_0', async () => {
await expect(query({ query: getTestQuery })).resolves.toMatchObject({
data: {
test: {
api: '2_0',
},
},
})
})
})
})

View File

@ -1,14 +0,0 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { Query, Resolver } from 'type-graphql'
import { federationLogger as logger } from '@/server/logger'
import { GetTestApiResult } from '../../GetTestApiResult'
@Resolver()
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export class TestResolver {
@Query(() => GetTestApiResult)
async test(): Promise<GetTestApiResult> {
logger.info(`test api 2_0`)
return new GetTestApiResult('2_0')
}
}

View File

@ -1,13 +0,0 @@
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import { Field, ObjectType } from 'type-graphql'
@ObjectType()
// eslint-disable-next-line @typescript-eslint/no-unused-vars
export class GetTestApiResult {
constructor(apiVersion: string) {
this.api = apiVersion
}
@Field(() => String)
api: string
}

View File

@ -2,15 +2,15 @@ import { GraphQLSchema } from 'graphql'
import { buildSchema } from 'type-graphql'
// import isAuthorized from './directive/isAuthorized'
import DecimalScalar from './scalar/Decimal'
import Decimal from 'decimal.js-light'
// import DecimalScalar from './scalar/Decimal'
// import Decimal from 'decimal.js-light'
import { getApiResolvers } from './api/schema'
const schema = async (): Promise<GraphQLSchema> => {
return await buildSchema({
resolvers: [getApiResolvers()],
// authChecker: isAuthorized,
scalarsMap: [{ type: Decimal, scalar: DecimalScalar }],
// scalarsMap: [{ type: Decimal, scalar: DecimalScalar }],
})
}

View File

@ -1,11 +1,12 @@
<template>
<div class="redeem-information">
<b-jumbotron bg-variant="muted" text-variant="dark" border-variant="info">
<h1 v-if="isContributionLink">
<h1 v-if="amount === ''">{{ $t('gdd_per_link.redeemlink-error') }}</h1>
<h1 v-if="isContributionLink && amount !== ''">
{{ CONFIG.COMMUNITY_NAME }}
{{ $t('contribution-link.thanksYouWith') }} {{ amount | GDD }}
</h1>
<h1 v-else>
<h1 v-if="!isContributionLink && amount !== ''">
{{ user.firstName }}
{{ $t('transaction-link.send_you') }} {{ amount | GDD }}
</h1>

View File

@ -3,7 +3,12 @@
<redeem-information v-bind="linkData" :isContributionLink="isContributionLink" />
<b-jumbotron>
<div class="mb-3 text-center">
<b-button variant="gradido" @click="$emit('mutation-link', linkData.amount)" size="lg">
<b-button
variant="gradido"
@click="$emit('mutation-link', linkData.amount)"
size="lg"
:disabled="!validLink"
>
{{ $t('gdd_per_link.redeem') }}
</b-button>
</div>
@ -21,6 +26,7 @@ export default {
props: {
linkData: { type: Object, required: true },
isContributionLink: { type: Boolean, default: false },
validLink: { type: Boolean, default: false },
},
}
</script>

View File

@ -210,6 +210,7 @@
"redeemed": "Erfolgreich eingelöst! Deinem Konto wurden {n} GDD gutgeschrieben.",
"redeemed-at": "Der Link wurde bereits am {date} eingelöst.",
"redeemed-title": "eingelöst",
"redeemlink-error": "Dieser Einlöse-Link ist nicht vollständig.",
"to-login": "Log dich ein",
"to-register": "Registriere ein neues Konto.",
"validUntil": "Gültig bis",

View File

@ -210,6 +210,7 @@
"redeemed": "Successfully redeemed! Your account has been credited with {n} GDD.",
"redeemed-at": "The link was already redeemed on {date}.",
"redeemed-title": "redeemed",
"redeemlink-error": "This redemption link is not complete.",
"to-login": "Log in",
"to-register": "Register a new account.",
"validUntil": "Valid until",

View File

@ -374,12 +374,12 @@ describe('TransactionLink', () => {
describe('error on transaction link query', () => {
beforeEach(() => {
apolloQueryMock.mockRejectedValue({ message: 'Ouchh!' })
apolloQueryMock.mockRejectedValue({ message: 'gdd_per_link.redeemlink-error' })
wrapper = Wrapper()
})
it('toasts an error message', () => {
expect(toastErrorSpy).toBeCalledWith('Ouchh!')
expect(toastErrorSpy).toBeCalledWith('gdd_per_link.redeemlink-error')
})
})
})

View File

@ -14,6 +14,7 @@
<redeem-valid
:linkData="linkData"
:isContributionLink="isContributionLink"
:validLink="validLink"
@mutation-link="mutationLink"
/>
</template>
@ -47,12 +48,13 @@ export default {
return {
linkData: {
__typename: 'TransactionLink',
amount: '123.45',
memo: 'memo',
amount: '',
memo: '',
user: {
firstName: 'Bibi',
firstName: '',
},
deletedAt: null,
validLink: false,
},
}
},
@ -67,13 +69,14 @@ export default {
},
})
.then((result) => {
this.validLink = true
this.linkData = result.data.queryTransactionLink
if (this.linkData.__typename === 'ContributionLink' && this.$store.state.token) {
this.mutationLink(this.linkData.amount)
}
})
.catch((err) => {
this.toastError(err.message)
.catch(() => {
this.toastError(this.$t('gdd_per_link.redeemlink-error'))
})
},
mutationLink(amount) {