Merge branch 'master' into message-type-admin-frontend

This commit is contained in:
Moriz Wahl 2023-06-29 14:47:37 +02:00 committed by GitHub
commit b56d7a7d2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
53 changed files with 1495 additions and 630 deletions

View File

@ -40,7 +40,7 @@ module.exports = {
],
// import
'import/export': 'error',
'import/no-deprecated': 'error',
// 'import/no-deprecated': 'error',
'import/no-empty-named-blocks': 'error',
'import/no-extraneous-dependencies': 'error',
'import/no-mutable-exports': 'error',

View File

@ -1,25 +1,39 @@
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { ObjectType, Field, Float, Int } from 'type-graphql'
import { GdtEntryType } from '@enum/GdtEntryType'
@ObjectType()
export class GdtEntry {
constructor(json: any) {
this.id = json.id
this.amount = json.amount
this.date = json.date
this.email = json.email
this.comment = json.comment
this.couponCode = json.coupon_code
this.gdtEntryType = json.gdt_entry_type_id
this.factor = json.factor
this.amount2 = json.amount2
this.factor2 = json.factor2
this.gdt = json.gdt
constructor({
id,
amount,
date,
email,
comment,
// eslint-disable-next-line camelcase
coupon_code,
// eslint-disable-next-line camelcase
gdt_entry_type_id,
factor,
amount2,
factor2,
gdt,
}: any) {
this.id = id
this.amount = amount
this.date = date
this.email = email
this.comment = comment
// eslint-disable-next-line camelcase
this.couponCode = coupon_code
// eslint-disable-next-line camelcase
this.gdtEntryType = gdt_entry_type_id
this.factor = factor
this.amount2 = amount2
this.factor2 = factor2
this.gdt = gdt
}
@Field(() => Int)

View File

@ -1,20 +1,15 @@
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
import { ObjectType, Field, Int, Float } from 'type-graphql'
import { GdtEntry } from './GdtEntry'
@ObjectType()
export class GdtEntryList {
constructor(json: any) {
this.status = json.state
this.count = json.count
this.gdtEntries = json.gdtEntries ? json.gdtEntries.map((json: any) => new GdtEntry(json)) : []
this.gdtSum = json.gdtSum
this.timeUsed = json.timeUsed
constructor(status = '', count = 0, gdtEntries = [], gdtSum = 0, timeUsed = 0) {
this.status = status
this.count = count
this.gdtEntries = gdtEntries
this.gdtSum = gdtSum
this.timeUsed = timeUsed
}
@Field(() => String)

View File

@ -1,12 +1,11 @@
/* eslint-disable @typescript-eslint/restrict-template-expressions */
import { getCustomRepository } from '@dbTools/typeorm'
import { IsNull } from '@dbTools/typeorm'
import { Transaction as dbTransaction } from '@entity/Transaction'
import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink'
import { Decimal } from 'decimal.js-light'
import { Resolver, Query, Ctx, Authorized } from 'type-graphql'
import { Balance } from '@model/Balance'
import { TransactionLinkRepository } from '@repository/TransactionLink'
import { RIGHTS } from '@/auth/RIGHTS'
import { Context, getUser } from '@/server/context'
@ -15,6 +14,7 @@ import { calculateDecay } from '@/util/decay'
import { GdtResolver } from './GdtResolver'
import { getLastTransaction } from './util/getLastTransaction'
import { transactionLinkSummary } from './util/transactionLinkSummary'
@Resolver()
export class BalanceResolver {
@ -57,7 +57,7 @@ export class BalanceResolver {
const linkCount = await dbTransactionLink.count({
where: {
userId: user.id,
redeemedAt: null,
redeemedAt: IsNull(),
// validUntil: MoreThan(new Date()),
},
})
@ -77,10 +77,9 @@ export class BalanceResolver {
)
// The final balance is reduced by the link amount withheld
const transactionLinkRepository = getCustomRepository(TransactionLinkRepository)
const { sumHoldAvailableAmount } = context.sumHoldAvailableAmount
? { sumHoldAvailableAmount: context.sumHoldAvailableAmount }
: await transactionLinkRepository.summary(user.id, now)
: await transactionLinkSummary(user.id, now)
logger.debug(`context.sumHoldAvailableAmount=${context.sumHoldAvailableAmount}`)
logger.debug(`sumHoldAvailableAmount=${sumHoldAvailableAmount}`)

View File

@ -542,7 +542,7 @@ describe('Contribution Links', () => {
})
it('updated the DB record', async () => {
await expect(DbContributionLink.findOne(linkId)).resolves.toEqual(
await expect(DbContributionLink.findOne({ where: { id: linkId } })).resolves.toEqual(
expect.objectContaining({
id: linkId,
name: 'Dokumenta 2023',

View File

@ -103,7 +103,7 @@ export class ContributionLinkResolver {
@Arg('id', () => Int) id: number,
@Ctx() context: Context,
): Promise<boolean> {
const dbContributionLink = await DbContributionLink.findOne(id)
const dbContributionLink = await DbContributionLink.findOne({ where: { id } })
if (!dbContributionLink) {
throw new LogError('Contribution Link not found', id)
}
@ -130,7 +130,7 @@ export class ContributionLinkResolver {
@Arg('id', () => Int) id: number,
@Ctx() context: Context,
): Promise<ContributionLink> {
const dbContributionLink = await DbContributionLink.findOne(id)
const dbContributionLink = await DbContributionLink.findOne({ where: { id } })
if (!dbContributionLink) {
throw new LogError('Contribution Link not found', id)
}

View File

@ -38,7 +38,7 @@ export class ContributionMessageResolver {
await queryRunner.startTransaction('REPEATABLE READ')
const contributionMessage = DbContributionMessage.create()
try {
const contribution = await DbContribution.findOne({ id: contributionId })
const contribution = await DbContribution.findOne({ where: { id: contributionId } })
if (!contribution) {
throw new LogError('Contribution not found', contributionId)
}
@ -145,7 +145,7 @@ export class ContributionMessageResolver {
if (contribution.userId === moderator.id) {
throw new LogError('Admin can not answer on his own contribution', contributionId)
}
if (!contribution.user.emailContact) {
if (!contribution.user.emailContact && contribution.user.emailId) {
contribution.user.emailContact = await DbUserContact.findOneOrFail({
where: { id: contribution.user.emailId },
})

View File

@ -1,7 +1,7 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-explicit-any */
import { Connection } from '@dbTools/typeorm'
import { Connection, Equal } from '@dbTools/typeorm'
import { Contribution } from '@entity/Contribution'
import { Event as DbEvent } from '@entity/Event'
import { Transaction as DbTransaction } from '@entity/Transaction'
@ -457,7 +457,7 @@ describe('ContributionResolver', () => {
describe('contribution has wrong status', () => {
beforeAll(async () => {
const contribution = await Contribution.findOneOrFail({
id: pendingContribution.data.createContribution.id,
where: { id: pendingContribution.data.createContribution.id },
})
contribution.contributionStatus = ContributionStatus.DELETED
await contribution.save()
@ -469,7 +469,7 @@ describe('ContributionResolver', () => {
afterAll(async () => {
const contribution = await Contribution.findOneOrFail({
id: pendingContribution.data.createContribution.id,
where: { id: pendingContribution.data.createContribution.id },
})
contribution.contributionStatus = ContributionStatus.PENDING
await contribution.save()
@ -1828,7 +1828,7 @@ describe('ContributionResolver', () => {
creation = await Contribution.findOneOrFail({
where: {
memo: 'Herzlich Willkommen bei Gradido!',
amount: 400,
amount: Equal(new Decimal('400')),
},
})
})

View File

@ -101,7 +101,7 @@ export class ContributionResolver {
@Ctx() context: Context,
): Promise<boolean> {
const user = getUser(context)
const contribution = await DbContribution.findOne(id)
const contribution = await DbContribution.findOne({ where: { id } })
if (!contribution) {
throw new LogError('Contribution not found', id)
}
@ -395,7 +395,7 @@ export class ContributionResolver {
@Arg('id', () => Int) id: number,
@Ctx() context: Context,
): Promise<boolean> {
const contribution = await DbContribution.findOne(id)
const contribution = await DbContribution.findOne({ where: { id } })
if (!contribution) {
throw new LogError('Contribution not found', id)
}
@ -409,10 +409,10 @@ export class ContributionResolver {
) {
throw new LogError('Own contribution can not be deleted as admin')
}
const user = await DbUser.findOneOrFail(
{ id: contribution.userId },
{ relations: ['emailContact'] },
)
const user = await DbUser.findOneOrFail({
where: { id: contribution.userId },
relations: ['emailContact'],
})
contribution.contributionStatus = ContributionStatus.DELETED
contribution.deletedBy = moderator.id
await contribution.save()
@ -447,7 +447,7 @@ export class ContributionResolver {
const releaseLock = await TRANSACTIONS_LOCK.acquire()
try {
const clientTimezoneOffset = getClientTimezoneOffset(context)
const contribution = await DbContribution.findOne(id)
const contribution = await DbContribution.findOne({ where: { id } })
if (!contribution) {
throw new LogError('Contribution not found', id)
}
@ -461,10 +461,11 @@ export class ContributionResolver {
if (moderatorUser.id === contribution.userId) {
throw new LogError('Moderator can not confirm own contribution')
}
const user = await DbUser.findOneOrFail(
{ id: contribution.userId },
{ withDeleted: true, relations: ['emailContact'] },
)
const user = await DbUser.findOneOrFail({
where: { id: contribution.userId },
withDeleted: true,
relations: ['emailContact'],
})
if (user.deletedAt) {
throw new LogError('Can not confirm contribution since the user was deleted')
}
@ -565,9 +566,11 @@ export class ContributionResolver {
@Ctx() context: Context,
): Promise<boolean> {
const contributionToUpdate = await DbContribution.findOne({
id,
confirmedAt: IsNull(),
deniedBy: IsNull(),
where: {
id,
confirmedAt: IsNull(),
deniedBy: IsNull(),
},
})
if (!contributionToUpdate) {
throw new LogError('Contribution not found', id)
@ -582,10 +585,10 @@ export class ContributionResolver {
)
}
const moderator = getUser(context)
const user = await DbUser.findOne(
{ id: contributionToUpdate.userId },
{ relations: ['emailContact'] },
)
const user = await DbUser.findOne({
where: { id: contributionToUpdate.userId },
relations: ['emailContact'],
})
if (!user) {
throw new LogError('Could not find User of the Contribution', contributionToUpdate.userId)
}

View File

@ -6,6 +6,7 @@ import { Resolver, Query, Args, Ctx, Authorized, Arg, Int, Float } from 'type-gr
import { Paginated } from '@arg/Paginated'
import { Order } from '@enum/Order'
import { GdtEntry } from '@model/GdtEntry'
import { GdtEntryList } from '@model/GdtEntryList'
import { apiGet, apiPost } from '@/apis/HttpRequest'
@ -31,9 +32,17 @@ export class GdtResolver {
`${CONFIG.GDT_API_URL}/GdtEntries/listPerEmailApi/${userEntity.emailContact.email}/${currentPage}/${pageSize}/${order}`,
)
if (!resultGDT.success) {
throw new LogError(resultGDT.data)
return new GdtEntryList()
}
return new GdtEntryList(resultGDT.data)
const { state, count, gdtEntries, gdtSum, timeUsed } = resultGDT.data
return new GdtEntryList(
state,
count,
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-explicit-any
gdtEntries ? gdtEntries.map((data: any) => new GdtEntry(data)) : [],
gdtSum,
timeUsed,
)
} catch (err) {
throw new LogError('GDT Server is not reachable')
}

View File

@ -72,10 +72,10 @@ describe('KlicktippResolver', () => {
})
it('stores the NEWSLETTER_SUBSCRIBE event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.NEWSLETTER_SUBSCRIBE,
@ -121,10 +121,10 @@ describe('KlicktippResolver', () => {
})
it('stores the NEWSLETTER_UNSUBSCRIBE event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.NEWSLETTER_UNSUBSCRIBE,

View File

@ -456,10 +456,10 @@ describe('TransactionLinkResolver', () => {
})
it('stores the CONTRIBUTION_LINK_REDEEM event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.CONTRIBUTION_LINK_REDEEM,
@ -611,10 +611,10 @@ describe('TransactionLinkResolver', () => {
})
it('stores the TRANSACTION_LINK_CREATE event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.TRANSACTION_LINK_CREATE,
@ -664,10 +664,10 @@ describe('TransactionLinkResolver', () => {
})
it('stores the TRANSACTION_LINK_DELETE event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.TRANSACTION_LINK_DELETE,
@ -719,14 +719,14 @@ describe('TransactionLinkResolver', () => {
})
it('stores the TRANSACTION_LINK_REDEEM event in the database', async () => {
const creator = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const redeemer = await UserContact.findOneOrFail(
{ email: 'peter@lustig.de' },
{ relations: ['user'] },
)
const creator = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
const redeemer = await UserContact.findOneOrFail({
where: { email: 'peter@lustig.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.TRANSACTION_LINK_REDEEM,

View File

@ -80,6 +80,7 @@ export class TransactionLinkResolver {
// validate amount
const sendBalance = await calculateBalance(user.id, holdAvailableAmount.mul(-1), createdDate)
if (!sendBalance) {
throw new LogError('User has not enough GDD', user.id)
}
@ -108,7 +109,7 @@ export class TransactionLinkResolver {
): Promise<boolean> {
const user = getUser(context)
const transactionLink = await DbTransactionLink.findOne({ id })
const transactionLink = await DbTransactionLink.findOne({ where: { id } })
if (!transactionLink) {
throw new LogError('Transaction link not found', id)
}
@ -138,17 +139,22 @@ export class TransactionLinkResolver {
@Query(() => QueryLinkResult)
async queryTransactionLink(@Arg('code') code: string): Promise<typeof QueryLinkResult> {
if (code.match(/^CL-/)) {
const contributionLink = await DbContributionLink.findOneOrFail(
{ code: code.replace('CL-', '') },
{ withDeleted: true },
)
const contributionLink = await DbContributionLink.findOneOrFail({
where: { code: code.replace('CL-', '') },
withDeleted: true,
})
return new ContributionLink(contributionLink)
} else {
const transactionLink = await DbTransactionLink.findOneOrFail({ code }, { withDeleted: true })
const user = await DbUser.findOneOrFail({ id: transactionLink.userId })
const transactionLink = await DbTransactionLink.findOneOrFail({
where: { code },
withDeleted: true,
})
const user = await DbUser.findOneOrFail({ where: { id: transactionLink.userId } })
let redeemedBy: User | null = null
if (transactionLink?.redeemedBy) {
redeemedBy = new User(await DbUser.findOneOrFail({ id: transactionLink.redeemedBy }))
redeemedBy = new User(
await DbUser.findOneOrFail({ where: { id: transactionLink.redeemedBy } }),
)
}
return new TransactionLink(transactionLink, new User(user), redeemedBy)
}
@ -191,7 +197,7 @@ export class TransactionLinkResolver {
throw new LogError('Contribution link is no longer valid', contributionLink.validTo)
}
}
let alreadyRedeemed: DbContribution | undefined
let alreadyRedeemed: DbContribution | null
switch (contributionLink.cycle) {
case ContributionCycleType.ONCE: {
alreadyRedeemed = await queryRunner.manager
@ -302,15 +308,17 @@ export class TransactionLinkResolver {
return true
} else {
const now = new Date()
const transactionLink = await DbTransactionLink.findOne({ code })
const transactionLink = await DbTransactionLink.findOne({ where: { code } })
if (!transactionLink) {
throw new LogError('Transaction link not found', code)
}
const linkedUser = await DbUser.findOne(
{ id: transactionLink.userId },
{ relations: ['emailContact'] },
)
const linkedUser = await DbUser.findOne({
where: {
id: transactionLink.userId,
},
relations: ['emailContact'],
})
if (!linkedUser) {
throw new LogError('Linked user not found for given link', transactionLink.userId)
@ -378,7 +386,7 @@ export class TransactionLinkResolver {
@Arg('userId', () => Int)
userId: number,
): Promise<TransactionLinkResult> {
const user = await DbUser.findOne({ id: userId })
const user = await DbUser.findOne({ where: { id: userId } })
if (!user) {
throw new LogError('Could not find requested User', userId)
}

View File

@ -346,8 +346,10 @@ describe('send coins', () => {
it('stores the TRANSACTION_SEND event in the database', async () => {
// Find the exact transaction (sent one is the one with user[1] as user)
const transaction = await Transaction.find({
userId: user[1].id,
memo: 'unrepeatable memo',
where: {
userId: user[1].id,
memo: 'unrepeatable memo',
},
})
await expect(DbEvent.find()).resolves.toContainEqual(
@ -364,8 +366,10 @@ describe('send coins', () => {
it('stores the TRANSACTION_RECEIVE event in the database', async () => {
// Find the exact transaction (received one is the one with user[0] as user)
const transaction = await Transaction.find({
userId: user[0].id,
memo: 'unrepeatable memo',
where: {
userId: user[0].id,
memo: 'unrepeatable memo',
},
})
await expect(DbEvent.find()).resolves.toContainEqual(

View File

@ -2,7 +2,7 @@
/* eslint-disable new-cap */
/* eslint-disable @typescript-eslint/no-non-null-assertion */
import { getCustomRepository, getConnection, In } from '@dbTools/typeorm'
import { getConnection, In } from '@dbTools/typeorm'
import { Transaction as dbTransaction } from '@entity/Transaction'
import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink'
import { User as dbUser } from '@entity/User'
@ -16,7 +16,6 @@ import { TransactionTypeId } from '@enum/TransactionTypeId'
import { Transaction } from '@model/Transaction'
import { TransactionList } from '@model/TransactionList'
import { User } from '@model/User'
import { TransactionLinkRepository } from '@repository/TransactionLink'
import { RIGHTS } from '@/auth/RIGHTS'
import {
@ -38,6 +37,7 @@ import { MEMO_MAX_CHARS, MEMO_MIN_CHARS } from './const/const'
import { findUserByIdentifier } from './util/findUserByIdentifier'
import { getLastTransaction } from './util/getLastTransaction'
import { getTransactionList } from './util/getTransactionList'
import { transactionLinkSummary } from './util/transactionLinkSummary'
export const executeTransaction = async (
amount: Decimal,
@ -245,9 +245,8 @@ export class TransactionResolver {
const self = new User(user)
const transactions: Transaction[] = []
const transactionLinkRepository = getCustomRepository(TransactionLinkRepository)
const { sumHoldAvailableAmount, sumAmount, lastDate, firstDate, transactionLinkcount } =
await transactionLinkRepository.summary(user.id, now)
await transactionLinkSummary(user.id, now)
context.linkCount = transactionLinkcount
logger.debug(`transactionLinkcount=${transactionLinkcount}`)
context.sumHoldAvailableAmount = sumHoldAvailableAmount

View File

@ -195,10 +195,12 @@ describe('UserResolver', () => {
})
it('stores the USER_REGISTER event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'peter@lustig.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: {
email: 'peter@lustig.de',
},
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.USER_REGISTER,
@ -271,10 +273,10 @@ describe('UserResolver', () => {
})
it('stores the EMAIL_ACCOUNT_MULTIREGISTRATION event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'peter@lustig.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'peter@lustig.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.EMAIL_ACCOUNT_MULTIREGISTRATION,
@ -292,7 +294,7 @@ describe('UserResolver', () => {
variables: { ...variables, email: 'bibi@bloxberg.de', language: 'it' },
})
await expect(
UserContact.findOne({ email: 'bibi@bloxberg.de' }, { relations: ['user'] }),
UserContact.findOne({ where: { email: 'bibi@bloxberg.de' }, relations: ['user'] }),
).resolves.toEqual(
expect.objectContaining({
email: 'bibi@bloxberg.de',
@ -334,7 +336,7 @@ describe('UserResolver', () => {
})
// make Peter Lustig Admin
const peter = await User.findOneOrFail({ id: user[0].id })
const peter = await User.findOneOrFail({ where: { id: user[0].id } })
peter.isAdmin = new Date()
await peter.save()
@ -365,7 +367,7 @@ describe('UserResolver', () => {
it('sets the contribution link id', async () => {
await expect(
UserContact.findOne({ email: 'ein@besucher.de' }, { relations: ['user'] }),
UserContact.findOne({ where: { email: 'ein@besucher.de' }, relations: ['user'] }),
).resolves.toEqual(
expect.objectContaining({
user: expect.objectContaining({
@ -445,7 +447,7 @@ describe('UserResolver', () => {
memo: `testing transaction link`,
})
transactionLink = await TransactionLink.findOneOrFail()
transactionLink = await TransactionLink.findOneOrFail({ where: { userId: bob.id } })
resetToken()
@ -462,7 +464,7 @@ describe('UserResolver', () => {
it('sets the referrer id to bob baumeister id', async () => {
await expect(
UserContact.findOne({ email: 'which@ever.de' }, { relations: ['user'] }),
UserContact.findOne({ where: { email: 'which@ever.de' }, relations: ['user'] }),
).resolves.toEqual(
expect.objectContaining({
user: expect.objectContaining({ referrerId: bob.data.login.id }),
@ -529,16 +531,18 @@ describe('UserResolver', () => {
beforeAll(async () => {
await mutate({ mutation: createUser, variables: createUserVariables })
const emailContact = await UserContact.findOneOrFail({ email: createUserVariables.email })
const emailContact = await UserContact.findOneOrFail({
where: { email: createUserVariables.email },
})
emailVerificationCode = emailContact.emailVerificationCode.toString()
result = await mutate({
mutation: setPassword,
variables: { code: emailVerificationCode, password: 'Aa12345_' },
})
newUser = await User.findOneOrFail(
{ id: emailContact.userId },
{ relations: ['emailContact'] },
)
newUser = await User.findOneOrFail({
where: { id: emailContact.userId },
relations: ['emailContact'],
})
})
afterAll(async () => {
@ -571,7 +575,9 @@ describe('UserResolver', () => {
describe('no valid password', () => {
beforeAll(async () => {
await mutate({ mutation: createUser, variables: createUserVariables })
const emailContact = await UserContact.findOneOrFail({ email: createUserVariables.email })
const emailContact = await UserContact.findOneOrFail({
where: { email: createUserVariables.email },
})
emailVerificationCode = emailContact.emailVerificationCode.toString()
})
@ -697,10 +703,10 @@ describe('UserResolver', () => {
})
it('stores the USER_LOGIN event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.USER_LOGIN,
@ -879,10 +885,10 @@ describe('UserResolver', () => {
})
it('stores the USER_LOGOUT event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.USER_LOGOUT,
@ -1047,10 +1053,10 @@ describe('UserResolver', () => {
})
it('stores the EMAIL_FORGOT_PASSWORD event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.EMAIL_FORGOT_PASSWORD,
@ -1083,7 +1089,7 @@ describe('UserResolver', () => {
beforeAll(async () => {
await userFactory(testEnv, bibiBloxberg)
emailContact = await UserContact.findOneOrFail({ email: bibiBloxberg.email })
emailContact = await UserContact.findOneOrFail({ where: { email: bibiBloxberg.email } })
})
afterAll(async () => {
@ -1100,7 +1106,9 @@ describe('UserResolver', () => {
errors: [
// keep Whitspace in error message!
new GraphQLError(`Could not find any entity of type "UserContact" matching: {
"emailVerificationCode": "not-valid"
"where": {
"emailVerificationCode": "not-valid"
}
}`),
],
}),
@ -1175,20 +1183,20 @@ describe('UserResolver', () => {
locale: 'en',
},
})
await expect(User.findOne()).resolves.toEqual(
await expect(User.find()).resolves.toEqual([
expect.objectContaining({
firstName: 'Benjamin',
lastName: 'Blümchen',
language: 'en',
}),
)
])
})
it('stores the USER_INFO_UPDATE event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.USER_INFO_UPDATE,
@ -1212,11 +1220,11 @@ describe('UserResolver', () => {
alias: 'bibi_Bloxberg',
},
})
await expect(User.findOne()).resolves.toEqual(
await expect(User.find()).resolves.toEqual([
expect.objectContaining({
alias: 'bibi_Bloxberg',
}),
)
])
})
})
})
@ -1433,10 +1441,10 @@ describe('UserResolver', () => {
let bibi: User
beforeAll(async () => {
const usercontact = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const usercontact = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
bibi = usercontact.user
bibi.passwordEncryptionType = PasswordEncryptionType.EMAIL
bibi.password = SecretKeyCryptographyCreateKey(
@ -1450,10 +1458,10 @@ describe('UserResolver', () => {
it('changes to gradidoID on login', async () => {
await mutate({ mutation: login, variables })
const usercontact = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const usercontact = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
bibi = usercontact.user
expect(bibi).toEqual(
@ -1590,14 +1598,14 @@ describe('UserResolver', () => {
})
it('stores the ADMIN_USER_ROLE_SET event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const adminConatct = await UserContact.findOneOrFail(
{ email: 'peter@lustig.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
const adminConatct = await UserContact.findOneOrFail({
where: { email: 'peter@lustig.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.ADMIN_USER_ROLE_SET,
@ -1792,14 +1800,15 @@ describe('UserResolver', () => {
})
it('stores the ADMIN_USER_DELETE event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'], withDeleted: true },
)
const adminConatct = await UserContact.findOneOrFail(
{ email: 'peter@lustig.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
withDeleted: true,
})
const adminConatct = await UserContact.findOneOrFail({
where: { email: 'peter@lustig.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.ADMIN_USER_DELETE,
@ -1943,10 +1952,10 @@ describe('UserResolver', () => {
})
it('sends an account activation email', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
const activationLink = CONFIG.EMAIL_LINK_VERIFICATION.replace(
/{optin}/g,
userConatct.emailVerificationCode.toString(),
@ -1965,10 +1974,10 @@ describe('UserResolver', () => {
})
it('stores the EMAIL_ADMIN_CONFIRMATION event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.EMAIL_ADMIN_CONFIRMATION,
@ -2086,14 +2095,14 @@ describe('UserResolver', () => {
})
it('stores the ADMIN_USER_UNDELETE event in the database', async () => {
const userConatct = await UserContact.findOneOrFail(
{ email: 'bibi@bloxberg.de' },
{ relations: ['user'] },
)
const adminConatct = await UserContact.findOneOrFail(
{ email: 'peter@lustig.de' },
{ relations: ['user'] },
)
const userConatct = await UserContact.findOneOrFail({
where: { email: 'bibi@bloxberg.de' },
relations: ['user'],
})
const adminConatct = await UserContact.findOneOrFail({
where: { email: 'peter@lustig.de' },
relations: ['user'],
})
await expect(DbEvent.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventType.ADMIN_USER_UNDELETE,

View File

@ -2,7 +2,7 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/restrict-template-expressions */
import { getConnection, getCustomRepository, IsNull, Not } from '@dbTools/typeorm'
import { getConnection, IsNull, Not } from '@dbTools/typeorm'
import { ContributionLink as DbContributionLink } from '@entity/ContributionLink'
import { TransactionLink as DbTransactionLink } from '@entity/TransactionLink'
import { User as DbUser } from '@entity/User'
@ -23,7 +23,6 @@ import { UserContactType } from '@enum/UserContactType'
import { SearchAdminUsersResult } from '@model/AdminUser'
import { User } from '@model/User'
import { UserAdmin, SearchUsersResult } from '@model/UserAdmin'
import { UserRepository } from '@repository/User'
import { subscribe } from '@/apis/KlicktippController'
import { encode } from '@/auth/JWT'
@ -65,6 +64,7 @@ import { randombytes_random } from 'sodium-native'
import { FULL_CREATION_AVAILABLE } from './const/const'
import { getUserCreations } from './util/creations'
import { findUserByIdentifier } from './util/findUserByIdentifier'
import { findUsers } from './util/findUsers'
import { getKlicktippState } from './util/getKlicktippState'
import { validateAlias } from './util/validateAlias'
@ -82,13 +82,13 @@ const newEmailContact = (email: string, userId: number): DbUserContact => {
emailContact.type = UserContactType.USER_CONTACT_EMAIL
emailContact.emailChecked = false
emailContact.emailOptInTypeId = OptInType.EMAIL_OPT_IN_REGISTER
emailContact.emailVerificationCode = random(64)
emailContact.emailVerificationCode = random(64).toString()
logger.debug('newEmailContact...successful', emailContact)
return emailContact
}
// eslint-disable-next-line @typescript-eslint/ban-types
export const activationLink = (verificationCode: BigInt): string => {
export const activationLink = (verificationCode: string): string => {
logger.debug(`activationLink(${verificationCode})...`)
return CONFIG.EMAIL_LINK_SETPASSWORD.replace(/{optin}/g, verificationCode.toString())
}
@ -270,7 +270,7 @@ export class UserResolver {
if (redeemCode) {
if (redeemCode.match(/^CL-/)) {
const contributionLink = await DbContributionLink.findOne({
code: redeemCode.replace('CL-', ''),
where: { code: redeemCode.replace('CL-', '') },
})
logger.info('redeemCode found contributionLink', contributionLink)
if (contributionLink) {
@ -278,7 +278,7 @@ export class UserResolver {
eventRegisterRedeem.involvedContributionLink = contributionLink
}
} else {
const transactionLink = await DbTransactionLink.findOne({ code: redeemCode })
const transactionLink = await DbTransactionLink.findOne({ where: { code: redeemCode } })
logger.info('redeemCode found transactionLink', transactionLink)
if (transactionLink) {
dbUser.referrerId = transactionLink.userId
@ -352,7 +352,8 @@ export class UserResolver {
const user = await findUserByEmail(email).catch(() => {
logger.warn(`fail on find UserContact per ${email}`)
})
if (!user) {
if (!user || user.deletedAt) {
logger.warn(`no user found with ${email}`)
return true
}
@ -365,7 +366,7 @@ export class UserResolver {
user.emailContact.updatedAt = new Date()
user.emailContact.emailResendCount++
user.emailContact.emailVerificationCode = random(64)
user.emailContact.emailVerificationCode = random(64).toString()
user.emailContact.emailOptInTypeId = OptInType.EMAIL_OPT_IN_RESET_PASSWORD
await user.emailContact.save().catch(() => {
throw new LogError('Unable to save email verification code', user.emailContact)
@ -403,10 +404,10 @@ export class UserResolver {
}
// load code
const userContact = await DbUserContact.findOneOrFail(
{ emailVerificationCode: code },
{ relations: ['user'] },
).catch(() => {
const userContact = await DbUserContact.findOneOrFail({
where: { emailVerificationCode: code },
relations: ['user'],
}).catch(() => {
throw new LogError('Could not login with emailVerificationCode')
})
logger.debug('userContact loaded...')
@ -474,7 +475,9 @@ export class UserResolver {
@Query(() => Boolean)
async queryOptIn(@Arg('optIn') optIn: string): Promise<boolean> {
logger.info(`queryOptIn(${optIn})...`)
const userContact = await DbUserContact.findOneOrFail({ emailVerificationCode: optIn })
const userContact = await DbUserContact.findOneOrFail({
where: { emailVerificationCode: optIn },
})
logger.debug('found optInCode', userContact)
// Code is only valid for `CONFIG.EMAIL_CODE_VALID_TIME` minutes
if (!isEmailVerificationCodeValid(userContact.updatedAt || userContact.createdAt)) {
@ -601,9 +604,7 @@ export class UserResolver {
@Args()
{ currentPage = 1, pageSize = 25, order = Order.DESC }: Paginated,
): Promise<SearchAdminUsersResult> {
const userRepository = getCustomRepository(UserRepository)
const [users, count] = await userRepository.findAndCount({
const [users, count] = await DbUser.findAndCount({
where: {
isAdmin: Not(IsNull()),
},
@ -636,7 +637,6 @@ export class UserResolver {
@Ctx() context: Context,
): Promise<SearchUsersResult> {
const clientTimezoneOffset = getClientTimezoneOffset(context)
const userRepository = getCustomRepository(UserRepository)
const userFields = [
'id',
'firstName',
@ -646,7 +646,7 @@ export class UserResolver {
'deletedAt',
'isAdmin',
]
const [users, count] = await userRepository.findBySearchCriteriaPagedFiltered(
const [users, count] = await findUsers(
userFields.map((fieldName) => {
return 'user.' + fieldName
}),
@ -705,7 +705,7 @@ export class UserResolver {
@Ctx()
context: Context,
): Promise<Date | null> {
const user = await DbUser.findOne({ id: userId })
const user = await DbUser.findOne({ where: { id: userId } })
// user exists ?
if (!user) {
throw new LogError('Could not find user with given ID', userId)
@ -734,7 +734,7 @@ export class UserResolver {
}
await user.save()
await EVENT_ADMIN_USER_ROLE_SET(user, moderator)
const newUser = await DbUser.findOne({ id: userId })
const newUser = await DbUser.findOne({ where: { id: userId } })
return newUser ? newUser.isAdmin : null
}
@ -744,7 +744,7 @@ export class UserResolver {
@Arg('userId', () => Int) userId: number,
@Ctx() context: Context,
): Promise<Date | null> {
const user = await DbUser.findOne({ id: userId })
const user = await DbUser.findOne({ where: { id: userId } })
// user exists ?
if (!user) {
throw new LogError('Could not find user with given ID', userId)
@ -757,7 +757,7 @@ export class UserResolver {
// soft-delete user
await user.softRemove()
await EVENT_ADMIN_USER_DELETE(user, moderator)
const newUser = await DbUser.findOne({ id: userId }, { withDeleted: true })
const newUser = await DbUser.findOne({ where: { id: userId }, withDeleted: true })
return newUser ? newUser.deletedAt : null
}
@ -767,7 +767,7 @@ export class UserResolver {
@Arg('userId', () => Int) userId: number,
@Ctx() context: Context,
): Promise<Date | null> {
const user = await DbUser.findOne({ id: userId }, { withDeleted: true })
const user = await DbUser.findOne({ where: { id: userId }, withDeleted: true })
if (!user) {
throw new LogError('Could not find user with given ID', userId)
}
@ -819,10 +819,11 @@ export class UserResolver {
}
export async function findUserByEmail(email: string): Promise<DbUser> {
const dbUserContact = await DbUserContact.findOneOrFail(
{ email },
{ withDeleted: true, relations: ['user'] },
).catch(() => {
const dbUserContact = await DbUserContact.findOneOrFail({
where: { email },
withDeleted: true,
relations: ['user'],
}).catch(() => {
throw new LogError('No user with this credentials', email)
})
const dbUser = dbUserContact.user
@ -831,7 +832,10 @@ export async function findUserByEmail(email: string): Promise<DbUser> {
}
async function checkEmailExists(email: string): Promise<boolean> {
const userContact = await DbUserContact.findOne({ email }, { withDeleted: true })
const userContact = await DbUserContact.findOne({
where: { email },
withDeleted: true,
})
if (userContact) {
return true
}

View File

@ -7,20 +7,20 @@ import { LogError } from '@/server/LogError'
import { VALID_ALIAS_REGEX } from './validateAlias'
export const findUserByIdentifier = async (identifier: string): Promise<DbUser> => {
let user: DbUser | undefined
let user: DbUser | null
if (validate(identifier) && version(identifier) === 4) {
user = await DbUser.findOne({ where: { gradidoID: identifier }, relations: ['emailContact'] })
if (!user) {
throw new LogError('No user found to given identifier', identifier)
}
} else if (/^.{2,}@.{2,}\..{2,}$/.exec(identifier)) {
const userContact = await DbUserContact.findOne(
{
const userContact = await DbUserContact.findOne({
where: {
email: identifier,
emailChecked: true,
},
{ relations: ['user'] },
)
relations: ['user'],
})
if (!userContact) {
throw new LogError('No user with this credentials', identifier)
}

View File

@ -1,20 +1,24 @@
import { Brackets, EntityRepository, IsNull, Not, Repository } from '@dbTools/typeorm'
import { getConnection, Brackets, IsNull, Not } from '@dbTools/typeorm'
import { User as DbUser } from '@entity/User'
import { SearchUsersFilters } from '@arg/SearchUsersFilters'
import { Order } from '@enum/Order'
@EntityRepository(DbUser)
export class UserRepository extends Repository<DbUser> {
async findBySearchCriteriaPagedFiltered(
select: string[],
searchCriteria: string,
filters: SearchUsersFilters | null,
currentPage: number,
pageSize: number,
order = Order.ASC,
): Promise<[DbUser[], number]> {
const query = this.createQueryBuilder('user')
import { LogError } from '@/server/LogError'
export const findUsers = async (
select: string[],
searchCriteria: string,
filters: SearchUsersFilters | null,
currentPage: number,
pageSize: number,
order = Order.ASC,
): Promise<[DbUser[], number]> => {
const queryRunner = getConnection().createQueryRunner()
try {
await queryRunner.connect()
const query = queryRunner.manager
.createQueryBuilder(DbUser, 'user')
.select(select)
.withDeleted()
.leftJoinAndSelect('user.emailContact', 'emailContact')
@ -30,27 +34,24 @@ export class UserRepository extends Repository<DbUser> {
)
}),
)
/*
filterCriteria.forEach((filter) => {
query.andWhere(filter)
})
*/
if (filters) {
if (filters.byActivated !== null) {
query.andWhere('emailContact.emailChecked = :value', { value: filters.byActivated })
// filterCriteria.push({ 'emailContact.emailChecked': filters.byActivated })
}
if (filters.byDeleted !== null) {
// filterCriteria.push({ deletedAt: filters.byDeleted ? Not(IsNull()) : IsNull() })
query.andWhere({ deletedAt: filters.byDeleted ? Not(IsNull()) : IsNull() })
}
}
return query
return await query
.orderBy({ 'user.id': order })
.take(pageSize)
.skip((currentPage - 1) * pageSize)
.getManyAndCount()
} catch (err) {
throw new LogError('Unable to search users', err)
} finally {
await queryRunner.release()
}
}

View File

@ -3,12 +3,10 @@ import { Transaction as DbTransaction } from '@entity/Transaction'
export const getLastTransaction = async (
userId: number,
relations?: string[],
): Promise<DbTransaction | undefined> => {
return DbTransaction.findOne(
{ userId },
{
order: { balanceDate: 'DESC', id: 'DESC' },
relations,
},
)
): Promise<DbTransaction | null> => {
return DbTransaction.findOne({
where: { userId },
order: { balanceDate: 'DESC', id: 'DESC' },
relations,
})
}

View File

@ -1,4 +1,4 @@
import { MoreThan } from '@dbTools/typeorm'
import { MoreThan, IsNull } from '@dbTools/typeorm'
import { TransactionLink as DbTransactionLink } from '@entity/TransactionLink'
import { User as DbUser } from '@entity/User'
@ -22,7 +22,7 @@ export async function transactionLinkList(
const [transactionLinks, count] = await DbTransactionLink.findAndCount({
where: {
userId: user.id,
...(!withRedeemed && { redeemedBy: null }),
...(!withRedeemed && { redeemedBy: IsNull() }),
...(!withExpired && { validUntil: MoreThan(new Date()) }),
},
withDeleted,

View File

@ -0,0 +1,49 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
import { getConnection } from '@dbTools/typeorm'
import { TransactionLink as DbTransactionLink } from '@entity/TransactionLink'
import { Decimal } from 'decimal.js-light'
import { LogError } from '@/server/LogError'
export const transactionLinkSummary = async (
userId: number,
date: Date,
): Promise<{
sumHoldAvailableAmount: Decimal
sumAmount: Decimal
lastDate: Date | null
firstDate: Date | null
transactionLinkcount: number
}> => {
const queryRunner = getConnection().createQueryRunner()
try {
await queryRunner.connect()
const { sumHoldAvailableAmount, sumAmount, lastDate, firstDate, count } =
await queryRunner.manager
.createQueryBuilder(DbTransactionLink, 'transactionLink')
.select('SUM(transactionLink.holdAvailableAmount)', 'sumHoldAvailableAmount')
.addSelect('SUM(transactionLink.amount)', 'sumAmount')
.addSelect('MAX(transactionLink.validUntil)', 'lastDate')
.addSelect('MIN(transactionLink.createdAt)', 'firstDate')
.addSelect('COUNT(*)', 'count')
.where('transactionLink.userId = :userId', { userId })
.andWhere('transactionLink.redeemedAt is NULL')
.andWhere('transactionLink.validUntil > :date', { date })
.orderBy('transactionLink.createdAt', 'DESC')
.getRawOne()
return {
sumHoldAvailableAmount: sumHoldAvailableAmount
? new Decimal(sumHoldAvailableAmount)
: new Decimal(0),
sumAmount: sumAmount ? new Decimal(sumAmount) : new Decimal(0),
lastDate: lastDate || null,
firstDate: firstDate || null,
transactionLinkcount: count || 0,
}
} catch (err) {
throw new LogError('Unable to get transaction link summary', err)
} finally {
await queryRunner.release()
}
}

View File

@ -95,7 +95,7 @@ describe('validate alias', () => {
describe('test against existing alias in database', () => {
beforeAll(async () => {
const bibi = await userFactory(testEnv, bibiBloxberg)
const user = await User.findOne({ id: bibi.id })
const user = await User.findOne({ where: { id: bibi.id } })
if (user) {
user.alias = 'b-b'
await user.save()

View File

@ -19,7 +19,10 @@ export const creationFactory = async (
creation: CreationInterface,
): Promise<Contribution> => {
const { mutate } = client
await mutate({ mutation: login, variables: { email: creation.email, password: 'Aa12345_' } })
await mutate({
mutation: login,
variables: { email: creation.email, password: 'Aa12345_' },
})
const {
data: { createContribution: contribution },
@ -30,7 +33,9 @@ export const creationFactory = async (
await mutate({ mutation: login, variables: { email: 'peter@lustig.de', password: 'Aa12345_' } })
await mutate({ mutation: confirmContribution, variables: { id: contribution.id } })
const confirmedContribution = await Contribution.findOneOrFail({ id: contribution.id })
const confirmedContribution = await Contribution.findOneOrFail({
where: { id: contribution.id },
})
if (creation.moveCreationDate) {
const transaction = await Transaction.findOneOrFail({

View File

@ -32,7 +32,7 @@ export const transactionLinkFactory = async (
} = await mutate({ mutation: createTransactionLink, variables })
if (transactionLink.createdAt || transactionLink.deletedAt) {
const dbTransactionLink = await TransactionLink.findOneOrFail({ id })
const dbTransactionLink = await TransactionLink.findOneOrFail({ where: { id } })
if (transactionLink.createdAt) {
dbTransactionLink.createdAt = transactionLink.createdAt

View File

@ -19,7 +19,7 @@ export const userFactory = async (
} = await mutate({ mutation: createUser, variables: user })
// console.log('creatUser:', { id }, { user })
// get user from database
let dbUser = await User.findOneOrFail({ id }, { relations: ['emailContact'] })
let dbUser = await User.findOneOrFail({ where: { id }, relations: ['emailContact'] })
// console.log('dbUser:', dbUser)
const emailContact = dbUser.emailContact
@ -33,7 +33,7 @@ export const userFactory = async (
}
// get last changes of user from database
dbUser = await User.findOneOrFail({ id })
dbUser = await User.findOneOrFail({ where: { id } })
if (user.createdAt || user.deletedAt || user.isAdmin) {
if (user.createdAt) dbUser.createdAt = user.createdAt

View File

@ -1,3 +1,9 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-return */
import { entities } from '@entity/index'
import { createTestClient } from 'apollo-server-testing'
import { name, internet, datatype } from 'faker'
@ -36,12 +42,10 @@ export const cleanDB = async () => {
}
}
const [entityTypes] = entities
const resetEntity = async (entity: typeof entityTypes) => {
const resetEntity = async (entity: any) => {
const items = await entity.find({ withDeleted: true })
if (items.length > 0) {
const ids = items.map((i) => i.id)
const ids = items.map((e: any) => e.id)
await entity.delete(ids)
}
}

View File

@ -15,7 +15,7 @@ export interface Context {
clientTimezoneOffset?: number
gradidoID?: string
// hack to use less DB calls for Balance Resolver
lastTransaction?: dbTransaction
lastTransaction?: dbTransaction | null
transactionCount?: number
linkCount?: number
sumHoldAvailableAmount?: Decimal

View File

@ -4,7 +4,7 @@ import { backendLogger as logger } from '@/server/logger'
const getDBVersion = async (): Promise<string | null> => {
try {
const dbVersion = await Migration.findOne({ order: { version: 'DESC' } })
const [dbVersion] = await Migration.find({ order: { version: 'DESC' }, take: 1 })
return dbVersion ? dbVersion.fileName : null
} catch (error) {
logger.error(error)

View File

@ -1,41 +0,0 @@
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-argument */
import { Repository, EntityRepository } from '@dbTools/typeorm'
import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink'
import { Decimal } from 'decimal.js-light'
@EntityRepository(dbTransactionLink)
export class TransactionLinkRepository extends Repository<dbTransactionLink> {
async summary(
userId: number,
date: Date,
): Promise<{
sumHoldAvailableAmount: Decimal
sumAmount: Decimal
lastDate: Date | null
firstDate: Date | null
transactionLinkcount: number
}> {
const { sumHoldAvailableAmount, sumAmount, lastDate, firstDate, count } =
await this.createQueryBuilder('transactionLinks')
.select('SUM(transactionLinks.holdAvailableAmount)', 'sumHoldAvailableAmount')
.addSelect('SUM(transactionLinks.amount)', 'sumAmount')
.addSelect('MAX(transactionLinks.validUntil)', 'lastDate')
.addSelect('MIN(transactionLinks.createdAt)', 'firstDate')
.addSelect('COUNT(*)', 'count')
.where('transactionLinks.userId = :userId', { userId })
.andWhere('transactionLinks.redeemedAt is NULL')
.andWhere('transactionLinks.validUntil > :date', { date })
.orderBy('transactionLinks.createdAt', 'DESC')
.getRawOne()
return {
sumHoldAvailableAmount: sumHoldAvailableAmount
? new Decimal(sumHoldAvailableAmount)
: new Decimal(0),
sumAmount: sumAmount ? new Decimal(sumAmount) : new Decimal(0),
lastDate: lastDate || null,
firstDate: firstDate || null,
transactionLinkcount: count || 0,
}
}
}

View File

@ -1,6 +1,6 @@
import { LoginElopageBuys } from '@entity/LoginElopageBuys'
export async function hasElopageBuys(email: string): Promise<boolean> {
const elopageBuyCount = await LoginElopageBuys.count({ payerEmail: email })
const elopageBuyCount = await LoginElopageBuys.count({ where: { payerEmail: email } })
return elopageBuyCount > 0
}

View File

@ -1,11 +1,10 @@
import { getCustomRepository } from '@dbTools/typeorm'
import { TransactionLink as dbTransactionLink } from '@entity/TransactionLink'
import { Decimal } from 'decimal.js-light'
import { Decay } from '@model/Decay'
import { TransactionLinkRepository } from '@repository/TransactionLink'
import { getLastTransaction } from '@/graphql/resolver/util/getLastTransaction'
import { transactionLinkSummary } from '@/graphql/resolver/util/transactionLinkSummary'
import { calculateDecay } from './decay'
@ -29,8 +28,7 @@ async function calculateBalance(
const decay = calculateDecay(lastTransaction.balance, lastTransaction.balanceDate, time)
const balance = decay.balance.add(amount.toString())
const transactionLinkRepository = getCustomRepository(TransactionLinkRepository)
const { sumHoldAvailableAmount } = await transactionLinkRepository.summary(userId, time)
const { sumHoldAvailableAmount } = await transactionLinkSummary(userId, time)
// If we want to redeem a link we need to make sure that the link amount is not considered as blocked
// else we cannot redeem links which are more or equal to half of what an account actually owns

View File

@ -135,7 +135,7 @@ export const elopageWebhook = async (req: any, res: any): Promise<void> => {
// Do we already have such a user?
// if ((await dbUser.count({ email })) !== 0) {
if ((await dbUserContact.count({ email })) !== 0) {
if ((await dbUserContact.count({ where: { email } })) !== 0) {
// eslint-disable-next-line no-console
console.log(`Did not create User - already exists with email: ${email}`)
return

View File

@ -1,4 +1,10 @@
/* eslint-disable @typescript-eslint/unbound-method */
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
/* eslint-disable @typescript-eslint/no-explicit-any */
/* eslint-disable @typescript-eslint/no-unsafe-call */
/* eslint-disable @typescript-eslint/no-unsafe-return */
import { entities } from '@entity/index'
import { createTestClient } from 'apollo-server-testing'
@ -7,7 +13,6 @@ import { createServer } from '@/server/createServer'
import { i18n, logger } from './testSetup'
export const headerPushMock = jest.fn((t) => {
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment, @typescript-eslint/no-unsafe-member-access
context.token = t.value
})
@ -21,7 +26,7 @@ const context = {
}
export const cleanDB = async () => {
// this only works as lond we do not have foreign key constraints
// this only works as long we do not have foreign key constraints
for (const entity of entities) {
await resetEntity(entity)
}
@ -36,12 +41,10 @@ export const testEnvironment = async (testLogger = logger, testI18n = i18n) => {
return { mutate, query, con }
}
const [entityTypes] = entities
export const resetEntity = async (entity: typeof entityTypes) => {
export const resetEntity = async (entity: any) => {
const items = await entity.find({ withDeleted: true })
if (items.length > 0) {
const ids = items.map((i) => i.id)
const ids = items.map((e: any) => e.id)
await entity.delete(ids)
}
}

View File

@ -32,7 +32,7 @@ export class UserContact extends BaseEntity {
email: string
@Column({ name: 'email_verification_code', type: 'bigint', unsigned: true, unique: true })
emailVerificationCode: BigInt
emailVerificationCode: string
@Column({ name: 'email_opt_in_type_id' })
emailOptInTypeId: number

View File

@ -46,7 +46,7 @@
"mysql2": "^2.3.0",
"reflect-metadata": "^0.1.13",
"ts-mysql-migrate": "^1.0.2",
"typeorm": "^0.2.38",
"typeorm": "^0.3.16",
"uuid": "^8.3.2"
},
"engines": {

View File

@ -2,6 +2,13 @@
# yarn lockfile v1
"@babel/runtime@^7.21.0":
version "7.22.5"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.22.5.tgz#8564dd588182ce0047d55d7a75e93921107b57ec"
integrity sha512-ecjvYlnAaZ/KVneE/OdKYBYfgXV3Ptu6zQWmgEF7vwKhQnvVS6bjMD2XYgj+SNvQ1GfK/pjgokfPkC/2CO8CuA==
dependencies:
regenerator-runtime "^0.13.11"
"@cspotcode/source-map-consumer@0.8.0":
version "0.8.0"
resolved "https://registry.yarnpkg.com/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz#33bf4b7b39c178821606f669bbc447a6a629786b"
@ -106,10 +113,10 @@
picocolors "^1.0.0"
tslib "^2.5.0"
"@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==
"@sqltools/formatter@^1.2.5":
version "1.2.5"
resolved "https://registry.yarnpkg.com/@sqltools/formatter/-/formatter-1.2.5.tgz#3abc203c79b8c3e90fd6c156a0c62d5403520e12"
integrity sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==
"@tsconfig/node10@^1.0.7":
version "1.0.8"
@ -173,11 +180,6 @@
resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-8.3.4.tgz#bd86a43617df0594787d38b735f55c805becf1bc"
integrity sha512-c/I8ZRb51j+pYGAu5CrFMRxqZ2ke4y2grEBO5AUjgSkSk+qT2Ea+OdWElz/OiMf5MNpn2b17kuVBwZLQJXzihw==
"@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@^5.57.1":
version "5.59.9"
resolved "https://registry.yarnpkg.com/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.59.9.tgz#2604cfaf2b306e120044f901e20c8ed926debf15"
@ -292,11 +294,6 @@ ajv@^6.10.0, ajv@^6.12.4:
json-schema-traverse "^0.4.1"
uri-js "^4.2.2"
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@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75"
@ -307,11 +304,6 @@ ansi-regex@^5.0.1:
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304"
integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==
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@^4.0.0, ansi-styles@^4.1.0:
version "4.3.0"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
@ -324,10 +316,10 @@ any-promise@^1.0.0:
resolved "https://registry.yarnpkg.com/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f"
integrity sha1-q8av7tzqUugJzcA3au0845Y10X8=
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==
app-root-path@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/app-root-path/-/app-root-path-3.1.0.tgz#5971a2fc12ba170369a7a1ef018c71e6e47c2e86"
integrity sha512-biN3PwB2gUtjaYy/isrU3aNWI5w+fAfvHkSvCKeQGxhmYpwKFUxudR3Yya+KqVRHBmEDYh+/lTozYCFbmzX4nA==
arg@^4.1.0:
version "4.1.3"
@ -423,6 +415,13 @@ brace-expansion@^1.1.7:
balanced-match "^1.0.0"
concat-map "0.0.1"
brace-expansion@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-2.0.1.tgz#1edc459e0f0c548486ecf9fc99f2221364b9a0ae"
integrity sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==
dependencies:
balanced-match "^1.0.0"
braces@^3.0.1:
version "3.0.2"
resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107"
@ -465,18 +464,7 @@ callsites@^3.0.0:
resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
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@^4.0.0, chalk@^4.1.0:
chalk@^4.0.0, chalk@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
@ -505,6 +493,15 @@ cliui@^7.0.2:
strip-ansi "^6.0.0"
wrap-ansi "^7.0.0"
cliui@^8.0.1:
version "8.0.1"
resolved "https://registry.yarnpkg.com/cliui/-/cliui-8.0.1.tgz#0c04b075db02cbfe60dc8e6cf2f5486b1a3608aa"
integrity sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==
dependencies:
string-width "^4.2.0"
strip-ansi "^6.0.1"
wrap-ansi "^7.0.0"
color-convert@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
@ -553,6 +550,13 @@ crypto@^1.0.1:
resolved "https://registry.yarnpkg.com/crypto/-/crypto-1.0.1.tgz#2af1b7cad8175d24c8a1b0778255794a21803037"
integrity sha512-VxBKmeNcqQdiUQUW2Tzq0t377b54N2bMtXO/qiLa+6eRRmmC4qT3D4OnTGoT/U6O9aklQ/jTwbOtRMTTY8G0Ig==
date-fns@^2.29.3:
version "2.30.0"
resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.30.0.tgz#f367e644839ff57894ec6ac480de40cae4b0f4d0"
integrity sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==
dependencies:
"@babel/runtime" "^7.21.0"
debug@^3.2.7:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
@ -560,7 +564,7 @@ debug@^3.2.7:
dependencies:
ms "^2.1.1"
debug@^4.1.1, debug@^4.3.1:
debug@^4.1.1:
version "4.3.2"
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b"
integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==
@ -658,10 +662,10 @@ 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==
dotenv@^16.0.3:
version "16.3.1"
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.3.1.tgz#369034de7d7e5b120972693352a3bf112172cc3e"
integrity sha512-IPzF4w4/Rd94bA9imS68tZBaYyBWSCE47V1RGuMrB94iyTOIEwRmVL2x/4An+6mETpLrKJ5hQkB8W4kFAadeIQ==
emoji-regex@^8.0.0:
version "8.0.0"
@ -746,7 +750,7 @@ escalade@^3.1.1:
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5:
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=
@ -1054,11 +1058,6 @@ 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"
@ -1203,17 +1202,16 @@ 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==
glob@^8.1.0:
version "8.1.0"
resolved "https://registry.yarnpkg.com/glob/-/glob-8.1.0.tgz#d388f656593ef708ee3e34640fdfb99a9fd1c33e"
integrity sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.4"
minimatch "^5.0.1"
once "^1.3.0"
path-is-absolute "^1.0.0"
globals@^13.19.0:
version "13.20.0"
@ -1274,13 +1272,6 @@ graphemer@^1.4.0:
resolved "https://registry.yarnpkg.com/graphemer/-/graphemer-1.4.0.tgz#fb2f1d55e0e3a1849aeffc90c4fa0dd53a0e66c6"
integrity sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==
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"
@ -1594,7 +1585,7 @@ isexe@^2.0.0:
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
integrity sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=
js-yaml@^4.0.0, js-yaml@^4.1.0:
js-yaml@^4.1.0:
version "4.1.0"
resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-4.1.0.tgz#c1fb65f8f5017901cdd2c951864ba18458a10602"
integrity sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==
@ -1705,6 +1696,13 @@ minimatch@^3.0.5, minimatch@^3.1.2:
dependencies:
brace-expansion "^1.1.7"
minimatch@^5.0.1:
version "5.1.6"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.6.tgz#1cfcb8cf5522ea69952cd2af95ae09477f122a96"
integrity sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==
dependencies:
brace-expansion "^2.0.1"
minimist@^1.2.0:
version "1.2.5"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
@ -1715,10 +1713,10 @@ minimist@^1.2.6:
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.8.tgz#c1a464e7693302e082a075cee0c057741ac4772c"
integrity sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==
mkdirp@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
mkdirp@^2.1.3:
version "2.1.6"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-2.1.6.tgz#964fbcb12b2d8c5d6fbc62a963ac95a273e2cc19"
integrity sha512-+hEnITedc8LAtIP9u3HJDFIdcLV2vXP33sqLLIzkv1Db1zO/1OxbvYf0Y1OC/S/Qo5dxHXepofhmxL02PsKe+A==
ms@2.1.2:
version "2.1.2"
@ -1897,11 +1895,6 @@ 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=
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"
@ -2014,6 +2007,11 @@ reflect-metadata@^0.1.13:
resolved "https://registry.yarnpkg.com/reflect-metadata/-/reflect-metadata-0.1.13.tgz#67ae3ca57c972a2aa1642b10fe363fe32d49dc08"
integrity sha512-Ts1Y/anZELhSsjMcU605fU9RE4Oi3p5ORujwbIKXfWa+0Zxs510Qrmrce5/Jowq3cHSZSJqBjypxmHarc+vEWg==
regenerator-runtime@^0.13.11:
version "0.13.11"
resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
regexp-tree@~0.1.1:
version "0.1.27"
resolved "https://registry.yarnpkg.com/regexp-tree/-/regexp-tree-0.1.27.tgz#2198f0ef54518ffa743fe74d983b56ffd631b6cd"
@ -2114,11 +2112,6 @@ safe-regex@^2.1.1:
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@^6.3.0:
version "6.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
@ -2199,6 +2192,15 @@ string-width@^4.1.0, string-width@^4.2.0:
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.0"
string-width@^4.2.3:
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
dependencies:
emoji-regex "^8.0.0"
is-fullwidth-code-point "^3.0.0"
strip-ansi "^6.0.1"
string.prototype.trim@^1.2.7:
version "1.2.7"
resolved "https://registry.yarnpkg.com/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz#a68352740859f6893f14ce3ef1bb3037f7a90533"
@ -2233,13 +2235,6 @@ 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@^6.0.0:
version "6.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532"
@ -2274,11 +2269,6 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1:
resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.1.1.tgz#31f1281b3832630434831c310c01cccda8cbe006"
integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==
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@^7.1.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
@ -2376,11 +2366,6 @@ 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==
tslib@^2.5.0:
version "2.5.3"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.5.3.tgz#24944ba2d990940e6e982c4bea147aba80209913"
@ -2414,28 +2399,26 @@ typed-array-length@^1.0.4:
for-each "^0.3.3"
is-typed-array "^1.1.9"
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==
typeorm@^0.3.16:
version "0.3.17"
resolved "https://registry.yarnpkg.com/typeorm/-/typeorm-0.3.17.tgz#a73c121a52e4fbe419b596b244777be4e4b57949"
integrity sha512-UDjUEwIQalO9tWw9O2A4GU+sT3oyoUXheHJy4ft+RFdnRdQctdQ34L9SqE2p7LdwzafHx1maxT+bqXON+Qnmig==
dependencies:
"@sqltools/formatter" "^1.2.2"
app-root-path "^3.0.0"
"@sqltools/formatter" "^1.2.5"
app-root-path "^3.1.0"
buffer "^6.0.3"
chalk "^4.1.0"
chalk "^4.1.2"
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"
date-fns "^2.29.3"
debug "^4.3.4"
dotenv "^16.0.3"
glob "^8.1.0"
mkdirp "^2.1.3"
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"
tslib "^2.5.0"
uuid "^9.0.0"
yargs "^17.6.2"
typescript@^4.3.5:
version "4.3.5"
@ -2474,6 +2457,11 @@ uuid@^8.3.2:
resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2"
integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==
uuid@^9.0.0:
version "9.0.0"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-9.0.0.tgz#592f550650024a38ceb0c562f2f6aa435761efb5"
integrity sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==
which-boxed-primitive@^1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz#13757bc89b209b049fe5d86430e21cf40a89a8e6"
@ -2523,19 +2511,6 @@ wrappy@1:
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
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"
@ -2551,20 +2526,16 @@ 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-parser@^21.1.1:
version "21.1.1"
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-21.1.1.tgz#9096bceebf990d21bb31fa9516e0ede294a77d35"
integrity sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==
yargs@^16.0.0:
version "16.2.0"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-16.2.0.tgz#1c82bf0f6b6a66eafce7ef30e376f49a12477f66"
@ -2578,18 +2549,18 @@ yargs@^16.0.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==
yargs@^17.6.2:
version "17.7.2"
resolved "https://registry.yarnpkg.com/yargs/-/yargs-17.7.2.tgz#991df39aca675a192b816e1e0363f9d75d2aa269"
integrity sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==
dependencies:
cliui "^7.0.2"
cliui "^8.0.1"
escalade "^3.1.1"
get-caller-file "^2.0.5"
require-directory "^2.1.1"
string-width "^4.2.0"
string-width "^4.2.3"
y18n "^5.0.5"
yargs-parser "^20.2.2"
yargs-parser "^21.1.1"
yn@3.1.1:
version "3.1.1"
@ -2600,16 +2571,3 @@ yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
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==

View File

@ -234,7 +234,8 @@ crontab -l
This show all existing entries of the crontab for user `gradido`
To install/add the cronjob for a daily backup at 3:00am please
To install/add the cronjob for a daily backup at 3:00am please,
To install/add the cronjob for a daily klicktipp export at 4:00am please,
Run:
@ -244,4 +245,5 @@ crontab -e
and insert the following line
```bash
0 3 * * * ~/gradido/deployment/bare_metal/backup.sh
0 4 * * * cd ~/gradido/backend/ && yarn klicktipp && cd
```

View File

@ -340,7 +340,7 @@ describe('federation', () => {
},
]
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
result = await DbFederatedCommunity.find({ foreign: true })
result = await DbFederatedCommunity.find({ where: { foreign: true } })
})
afterAll(async () => {
@ -601,7 +601,7 @@ describe('federation', () => {
{ api: 'toolong api', url: 'some valid url' },
]
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
result = await DbFederatedCommunity.find({ foreign: true })
result = await DbFederatedCommunity.find({ where: { foreign: true } })
})
afterAll(async () => {
@ -655,7 +655,7 @@ describe('federation', () => {
},
]
await socketEventMocks.data(Buffer.from(JSON.stringify(jsonArray)))
result = await DbFederatedCommunity.find({ foreign: true })
result = await DbFederatedCommunity.find({ where: { foreign: true } })
})
afterAll(async () => {
@ -791,7 +791,7 @@ describe('federation', () => {
]),
),
)
result = await DbFederatedCommunity.find({ foreign: true })
result = await DbFederatedCommunity.find({ where: { foreign: true } })
})
afterAll(async () => {

View File

@ -217,7 +217,7 @@ async function writeFederatedHomeCommunityEntries(pubKey: string): Promise<Commu
async function writeHomeCommunityEntry(keyPair: KeyPair): Promise<void> {
try {
// check for existing homeCommunity entry
let homeCom = await DbCommunity.findOne({ foreign: false })
let homeCom = await DbCommunity.findOne({ where: { foreign: false } })
if (homeCom) {
// simply update the existing entry, but it MUST keep the ID and UUID because of possible relations
homeCom.publicKey = keyPair.publicKey

View File

@ -3,7 +3,7 @@ import { logger } from '@/server/logger'
const getDBVersion = async (): Promise<string | null> => {
try {
const dbVersion = await Migration.findOne({ order: { version: 'DESC' } })
const [dbVersion] = await Migration.find({ order: { version: 'DESC' }, take: 1 })
return dbVersion ? dbVersion.fileName : null
} catch (error) {
logger.error(error)

View File

@ -41,7 +41,6 @@ export default defineConfig({
e2e: {
specPattern: '**/*.feature',
excludeSpecPattern: '*.js',
experimentalSessionAndOrigin: true,
baseUrl: 'http://localhost:3000',
chromeWebSecurity: false,
defaultCommandTimeout: 10000,
@ -49,10 +48,7 @@ export default defineConfig({
viewportHeight: 720,
viewportWidth: 1280,
video: false,
retries: {
runMode: 2,
openMode: 0,
},
retries: 0,
env: {
backendURL: 'http://localhost:4000',
mailserverURL: 'http://localhost:1080',

View File

@ -1,4 +1,4 @@
import { And, Then, When } from '@badeball/cypress-cucumber-preprocessor'
import { Then, When } from '@badeball/cypress-cucumber-preprocessor'
import { SendPage } from '../../e2e/models/SendPage'
const sendPage = new SendPage()
@ -12,7 +12,7 @@ When(
},
)
And('the user submits the send form', () => {
When('the user submits the send form', () => {
sendPage.submit()
cy.get(sendPage.confirmationBox).should('be.visible')
})

View File

@ -1,4 +1,4 @@
import { When, And } from '@badeball/cypress-cucumber-preprocessor'
import { When } from '@badeball/cypress-cucumber-preprocessor'
import { ForgotPasswordPage } from '../../e2e/models/ForgotPasswordPage'
import { LoginPage } from '../../e2e/models/LoginPage'
import { ResetPasswordPage } from '../../e2e/models/ResetPasswordPage'
@ -31,7 +31,7 @@ When('the user submits the credentials {string} {string}', (email: string, passw
// password reset related
And('the user navigates to the forgot password page', () => {
When('the user navigates to the forgot password page', () => {
loginPage.openForgotPasswordPage()
cy.url().should('include', '/forgot-password')
})
@ -40,25 +40,25 @@ When('the user enters the e-mail address {string}', (email: string) => {
forgotPasswordPage.enterEmail(email)
})
And('the user submits the e-mail form', () => {
When('the user submits the e-mail form', () => {
forgotPasswordPage.submitEmail()
cy.get(forgotPasswordPage.successComponent).should('be.visible')
})
And('the user enters the password {string}', (password: string) => {
When('the user enters the password {string}', (password: string) => {
resetPasswordPage.enterNewPassword(password)
})
And('the user repeats the password {string}', (password: string) => {
When('the user repeats the password {string}', (password: string) => {
resetPasswordPage.repeatNewPassword(password)
})
And('the user submits the new password', () => {
When('the user submits the new password', () => {
resetPasswordPage.submitNewPassword()
cy.get(resetPasswordPage.resetPasswordMessageBlock).should('be.visible')
})
And('the user clicks the sign in button', () => {
When('the user clicks the sign in button', () => {
resetPasswordPage.openSigninPage()
cy.url().should('contain', '/login')
})

View File

@ -1,10 +1,10 @@
import { And, DataTable, When } from '@badeball/cypress-cucumber-preprocessor'
import { DataTable, When } from '@badeball/cypress-cucumber-preprocessor'
import { ProfilePage } from '../../e2e/models/ProfilePage'
import { Toasts } from '../../e2e/models/Toasts'
const profilePage = new ProfilePage()
And('the user opens the change password menu', () => {
When('the user opens the change password menu', () => {
cy.get(profilePage.openChangePassword).click()
cy.get(profilePage.newPasswordRepeatInput).should('be.visible')
cy.get(profilePage.submitNewPasswordBtn).should('be.disabled')
@ -18,7 +18,7 @@ When('the user fills the password form with:', (table: DataTable) => {
cy.get(profilePage.submitNewPasswordBtn).should('be.enabled')
})
And('the user submits the password form', () => {
When('the user submits the password form', () => {
profilePage.submitPasswordForm()
})

View File

@ -1,4 +1,4 @@
import { And, When } from '@badeball/cypress-cucumber-preprocessor'
import { When } from '@badeball/cypress-cucumber-preprocessor'
import { RegistrationPage } from '../../e2e/models/RegistrationPage'
const registrationPage = new RegistrationPage()
@ -13,11 +13,11 @@ When(
},
)
And('the user agrees to the privacy policy', () => {
When('the user agrees to the privacy policy', () => {
registrationPage.checkPrivacyCheckbox()
})
And('the user submits the registration form', () => {
When('the user submits the registration form', () => {
registrationPage.submitRegistrationForm()
cy.get(registrationPage.RegistrationThanxHeadline).should('be.visible')
cy.get(registrationPage.RegistrationThanxText).should('be.visible')

View File

@ -18,20 +18,20 @@
"lint": "eslint --max-warnings=0 --ext .js,.ts ."
},
"dependencies": {
"@badeball/cypress-cucumber-preprocessor": "^12.0.0",
"@badeball/cypress-cucumber-preprocessor": "^18.0.1",
"@cypress/browserify-preprocessor": "^3.0.2",
"@typescript-eslint/eslint-plugin": "^5.38.0",
"@typescript-eslint/parser": "^5.38.0",
"cypress": "^12.7.0",
"cypress": "^12.16.0",
"eslint": "^8.23.1",
"eslint-config-prettier": "^8.3.0",
"eslint-config-standard": "^16.0.3",
"eslint-loader": "^4.0.2",
"eslint-plugin-cypress": "^2.12.1",
"eslint-plugin-cypress": "^2.13.3",
"eslint-plugin-import": "^2.23.4",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-promise": "^5.1.0",
"eslint-plugin-promise": "^6.1.1",
"jwt-decode": "^3.1.2",
"prettier": "^2.7.1",
"typescript": "^4.7.4"

File diff suppressed because it is too large Load Diff

View File

@ -11,8 +11,10 @@ export class PublicKeyResolver {
async getPublicKey(): Promise<GetPublicKeyResult> {
logger.debug(`getPublicKey() via apiVersion=1_0 ...`)
const homeCom = await DbFederatedCommunity.findOneOrFail({
foreign: false,
apiVersion: '1_0',
where: {
foreign: false,
apiVersion: '1_0',
},
})
logger.info(`getPublicKey()-1_0... return publicKey=${homeCom.publicKey}`)
return new GetPublicKeyResult(homeCom.publicKey.toString())

View File

@ -3,7 +3,7 @@ import { federationLogger as logger } from '@/server/logger'
const getDBVersion = async (): Promise<string | null> => {
try {
const dbVersion = await Migration.findOne({ order: { version: 'DESC' } })
const [dbVersion] = await Migration.find({ order: { version: 'DESC' }, take: 1 })
return dbVersion ? dbVersion.fileName : null
} catch (error) {
logger.error(error)

View File

@ -276,7 +276,7 @@ export default {
} = result
this.GdtBalance =
transactionList.balance.balanceGDT === null
? null
? 0
: Number(transactionList.balance.balanceGDT)
this.transactions = transactionList.transactions
this.balance = Number(transactionList.balance.balance)

View File

@ -142,6 +142,7 @@ describe('Transactions', () => {
currentPage: 1,
pageSize: 25,
},
fetchPolicy: 'network-only',
})
})
@ -170,6 +171,7 @@ describe('Transactions', () => {
currentPage: 2,
pageSize: 25,
},
fetchPolicy: 'network-only',
})
})
})

View File

@ -59,6 +59,7 @@ export default {
currentPage: this.currentPage,
pageSize: this.pageSize,
},
fetchPolicy: 'network-only',
})
.then((result) => {
const {