more logging classes, fix test

This commit is contained in:
einhorn_b 2024-01-19 13:40:21 +01:00
parent 5cc7483136
commit 74186e21ae
17 changed files with 369 additions and 27 deletions

View File

@ -0,0 +1,45 @@
import { Contribution } from '../entity/Contribution'
import { AbstractLoggingView } from './AbstractLogging.view'
import { ContributionMessageLoggingView } from './ContributionMessageLogging.view'
import { TransactionLoggingView } from './TransactionLogging.view'
import { UserLoggingView } from './UserLogging.view'
export class ContributionLoggingView extends AbstractLoggingView {
public constructor(private self: Contribution) {
super()
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public toJSON(): any {
return {
id: this.self.id,
user: this.self.user
? new UserLoggingView(this.self.user).toJSON()
: { id: this.self.userId },
createdAt: this.dateToString(this.self.createdAt),
resubmissionAt: this.dateToString(this.self.resubmissionAt),
contributionDate: this.dateToString(this.self.contributionDate),
memoLength: this.self.memo.length,
amount: this.decimalToString(this.self.amount),
moderatorId: this.self.moderatorId,
contributionLinkId: this.self.contributionLinkId,
confirmedBy: this.self.confirmedBy,
confirmedAt: this.dateToString(this.self.confirmedAt),
deniedBy: this.self.deniedBy,
deniedAt: this.dateToString(this.self.deniedAt),
contributionType: this.self.contributionType,
contributionStatus: this.self.contributionStatus,
transactionId: this.self.transactionId,
updatedAt: this.dateToString(this.self.updatedAt),
updatedBy: this.self.updatedBy,
deletedAt: this.dateToString(this.self.deletedAt),
deletedBy: this.self.deletedBy,
messages: this.self.messages
? this.self.messages.map((message) => new ContributionMessageLoggingView(message).toJSON())
: undefined,
transaction: this.self.transaction
? new TransactionLoggingView(this.self.transaction).toJSON()
: { id: this.self.transactionId },
}
}
}

View File

@ -0,0 +1,30 @@
import { ContributionMessage } from '../entity/ContributionMessage'
import { AbstractLoggingView } from './AbstractLogging.view'
import { ContributionLoggingView } from './ContributionLogging.view'
import { UserLoggingView } from './UserLogging.view'
export class ContributionMessageLoggingView extends AbstractLoggingView {
public constructor(private self: ContributionMessage) {
super()
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public toJSON(): any {
return {
id: this.self.id,
contribution: this.self.contribution
? new ContributionLoggingView(this.self.contribution).toJSON()
: { id: this.self.contributionId },
user: this.self.user
? new UserLoggingView(this.self.user).toJSON()
: { id: this.self.userId },
messageLength: this.self.message.length,
createdAt: this.dateToString(this.self.createdAt),
updatedAt: this.dateToString(this.self.updatedAt),
deletedAt: this.dateToString(this.self.deletedAt),
deletedBy: this.self.deletedBy,
type: this.self.type,
isModerator: this.self.isModerator,
}
}
}

View File

@ -0,0 +1,23 @@
import { DltTransaction } from '../entity/DltTransaction'
import { AbstractLoggingView } from './AbstractLogging.view'
import { TransactionLoggingView } from './TransactionLogging.view'
export class DltTransactionLoggingView extends AbstractLoggingView {
public constructor(private self: DltTransaction) {
super()
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public toJSON(): any {
return {
id: this.self.id,
transaction: this.self.transaction
? new TransactionLoggingView(this.self.transaction).toJSON()
: { id: this.self.transactionId },
messageId: this.self.messageId,
verified: this.self.verified,
createdAt: this.dateToString(this.self.createdAt),
verifiedAt: this.dateToString(this.self.verifiedAt),
}
}
}

View File

@ -0,0 +1,27 @@
/* eslint-disable no-unused-vars */
import { PendingTransaction } from '../entity/PendingTransaction'
import { Transaction } from '../entity/Transaction'
import { AbstractLoggingView } from './AbstractLogging.view'
import { TransactionLoggingView } from './TransactionLogging.view'
// TODO: move enum into database, maybe rename database
enum PendingTransactionState {
NEW = 1,
PENDING = 2,
SETTLED = 3,
REVERTED = 4,
}
export class PendingTransactionLoggingView extends AbstractLoggingView {
public constructor(private self: PendingTransaction) {
super()
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public toJSON(): any {
return {
...new TransactionLoggingView(this.self as Transaction).toJSON(),
state: PendingTransactionState[this.self.state],
}
}
}

View File

@ -0,0 +1,56 @@
/* eslint-disable no-unused-vars */
import { Transaction } from '../entity/Transaction'
import { AbstractLoggingView } from './AbstractLogging.view'
import { ContributionLoggingView } from './ContributionLogging.view'
import { DltTransactionLoggingView } from './DltTransactionLogging.view'
// TODO: move enum into database, maybe rename database
enum TransactionTypeId {
CREATION = 1,
SEND = 2,
RECEIVE = 3,
// This is a virtual property, never occurring on the database
DECAY = 4,
LINK_SUMMARY = 5,
}
export class TransactionLoggingView extends AbstractLoggingView {
public constructor(private self: Transaction) {
super()
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public toJSON(): any {
return {
id: this.self.id,
previous: this.self.previous,
typeId: TransactionTypeId[this.self.typeId],
transactionLinkId: this.self.transactionLinkId,
amount: this.decimalToString(this.self.amount),
balance: this.decimalToString(this.self.balance),
balanceDate: this.dateToString(this.self.balanceDate),
decay: this.decimalToString(this.self.decay),
decayStart: this.dateToString(this.self.decayStart),
memoLength: this.self.memo.length,
creationDate: this.dateToString(this.self.creationDate),
userId: this.self.userId,
userCommunityUuid: this.self.userCommunityUuid,
userGradidoId: this.self.userGradidoID,
userName: this.self.userName?.substring(0, 3) + '...',
linkedUserId: this.self.linkedUserId,
linkedUserCommunityUuid: this.self.linkedUserCommunityUuid,
linkedUserGradidoID: this.self.linkedUserGradidoID,
linkedUserName: this.self.linkedUserName?.substring(0, 3) + '...',
linkedTransactionId: this.self.linkedTransactionId,
contribution: this.self.contribution
? new ContributionLoggingView(this.self.contribution)
: undefined,
dltTransaction: this.self.dltTransaction
? new DltTransactionLoggingView(this.self.dltTransaction).toJSON()
: undefined,
previousTransaction: this.self.previousTransaction
? new TransactionLoggingView(this.self.previousTransaction).toJSON()
: undefined,
}
}
}

View File

@ -0,0 +1,35 @@
/* eslint-disable no-unused-vars */
import { UserContact } from '../entity/UserContact'
import { AbstractLoggingView } from './AbstractLogging.view'
import { UserLoggingView } from './UserLogging.view'
enum OptInType {
EMAIL_OPT_IN_REGISTER = 1,
EMAIL_OPT_IN_RESET_PASSWORD = 2,
}
export class UserContactLoggingView extends AbstractLoggingView {
public constructor(private self: UserContact) {
super()
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public toJSON(): any {
return {
id: this.self.id,
type: this.self.type,
user: this.self.user
? new UserLoggingView(this.self.user).toJSON()
: { id: this.self.userId },
email: this.self.email?.substring(0, 3) + '...',
emailVerificationCode: this.self.emailVerificationCode?.substring(0, 4) + '...',
emailOptInTypeId: OptInType[this.self.emailOptInTypeId],
emailResendCount: this.self.emailResendCount,
emailChecked: this.self.emailChecked,
phone: this.self.phone ? this.self.phone.substring(0, 3) + '...' : undefined,
createdAt: this.dateToString(this.self.createdAt),
updatedAt: this.dateToString(this.self.updatedAt),
deletedAt: this.dateToString(this.self.deletedAt),
}
}
}

View File

@ -0,0 +1,60 @@
/* eslint-disable no-unused-vars */
import { User } from '../entity/User'
import { AbstractLoggingView } from './AbstractLogging.view'
import { ContributionLoggingView } from './ContributionLogging.view'
import { ContributionMessageLoggingView } from './ContributionMessageLogging.view'
import { UserContactLoggingView } from './UserContactLogging.view'
import { UserRoleLoggingView } from './UserRoleLogging.view'
enum PasswordEncryptionType {
NO_PASSWORD = 0,
EMAIL = 1,
GRADIDO_ID = 2,
}
export class UserLoggingView extends AbstractLoggingView {
public constructor(private self: User) {
super()
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public toJSON(): any {
return {
id: this.self.id,
foreign: this.self.foreign,
gradidoID: this.self.gradidoID,
communityUuid: this.self.communityUuid,
alias: this.self.alias?.substring(0, 3) + '...',
emailContact: this.self.emailContact
? new UserContactLoggingView(this.self.emailContact).toJSON()
: { id: this.self.emailId },
firstName: this.self.firstName?.substring(0, 3) + '...',
lastName: this.self.lastName?.substring(0, 3) + '...',
createdAt: this.dateToString(this.self.createdAt),
deletedAt: this.dateToString(this.self.deletedAt),
passwordEncryptionType: this.self.passwordEncryptionType as PasswordEncryptionType,
language: this.self.language,
hideAmountGDD: this.self.hideAmountGDD,
hideAmountGDT: this.self.hideAmountGDT,
userRoles: this.self.userRoles
? this.self.userRoles.map((userRole) => new UserRoleLoggingView(userRole).toJSON())
: undefined,
referrerId: this.self.referrerId,
contributionLinkId: this.self.contributionLinkId,
publisherId: this.self.publisherId,
contributions: this.self.contributions
? this.self.contributions.map((contribution) =>
new ContributionLoggingView(contribution).toJSON(),
)
: undefined,
messages: this.self.messages
? this.self.messages.map((message) => new ContributionMessageLoggingView(message).toJSON())
: undefined,
userContacts: this.self.userContacts
? this.self.userContacts.map((userContact) =>
new UserContactLoggingView(userContact).toJSON(),
)
: undefined,
}
}
}

View File

@ -0,0 +1,22 @@
import { UserRole } from '../entity/UserRole'
import { AbstractLoggingView } from './AbstractLogging.view'
import { UserLoggingView } from './UserLogging.view'
export class UserRoleLoggingView extends AbstractLoggingView {
public constructor(private self: UserRole) {
super()
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public toJSON(): any {
return {
id: this.self.id,
user: this.self.user
? new UserLoggingView(this.self.user).toJSON()
: { id: this.self.userId },
role: this.self.role,
createdAt: this.dateToString(this.self.createdAt),
updatedAt: this.dateToString(this.self.updatedAt),
}
}
}

View File

@ -24,6 +24,11 @@ module.exports = {
process.env.NODE_ENV === 'development'
? '<rootDir>/../database/entity/$1'
: '<rootDir>/../database/build/entity/$1',
'@logging/(.*)':
// eslint-disable-next-line n/no-process-env
process.env.NODE_ENV === 'development'
? '<rootDir>/../database/logging/$1'
: '<rootDir>/../database/build/logging/$1',
'@dbTools/(.*)':
process.env.NODE_ENV === 'development'
? '<rootDir>/../database/src/$1'

View File

@ -46,7 +46,10 @@ describe('PublicCommunityInfoResolver', () => {
homeCom.name = 'Community-Name'
homeCom.description = 'Community-Description'
homeCom.creationDate = new Date()
homeCom.publicKey = Buffer.from('homeCommunity-publicKey')
homeCom.publicKey = Buffer.from(
'316f2951501f27c664e188d5128505917e8673e8bebce141f86e70907e782a08',
'hex',
)
await DbCommunity.insert(homeCom)
})
@ -57,7 +60,7 @@ describe('PublicCommunityInfoResolver', () => {
name: 'Community-Name',
description: 'Community-Description',
creationDate: homeCom.creationDate?.toISOString(),
publicKey: expect.stringMatching('homeCommunity-publicKey'),
publicKey: '316f2951501f27c664e188d5128505917e8673e8bebce141f86e70907e782a08',
},
},
})

View File

@ -39,7 +39,10 @@ describe('PublicKeyResolver', () => {
homeCom.foreign = false
homeCom.apiVersion = '1_0'
homeCom.endPoint = 'endpoint-url'
homeCom.publicKey = Buffer.from('homeCommunity-publicKey')
homeCom.publicKey = Buffer.from(
'9f6dcd0d985cc7105cd71c3417d9c291b126c8ca90513197de02191f928ef713',
'hex',
)
await DbFederatedCommunity.insert(homeCom)
})
@ -47,7 +50,7 @@ describe('PublicKeyResolver', () => {
await expect(query({ query: getPublicKeyQuery })).resolves.toMatchObject({
data: {
getPublicKey: {
publicKey: expect.stringMatching('homeCommunity-publicKey'),
publicKey: '9f6dcd0d985cc7105cd71c3417d9c291b126c8ca90513197de02191f928ef713',
},
},
})

View File

@ -1,5 +1,6 @@
import { Arg, Mutation, Resolver } from 'type-graphql'
import { federationLogger as logger } from '@/server/logger'
import { PendingTransactionLoggingView } from '@logging/PendingTransactionLogging.view'
import { Community as DbCommunity } from '@entity/Community'
import { PendingTransaction as DbPendingTransaction } from '@entity/PendingTransaction'
import { SendCoinsArgs } from '../model/SendCoinsArgs'
@ -140,7 +141,10 @@ export class SendCoinsResolver {
linkedUserCommunityUuid: args.senderCommunityUuid,
linkedUserGradidoID: args.senderUserUuid,
})
logger.debug('XCom: revertSendCoins found pendingTX=', pendingTx)
logger.debug(
'XCom: revertSendCoins found pendingTX=',
pendingTx ? new PendingTransactionLoggingView(pendingTx) : 'null',
)
if (pendingTx && pendingTx.amount.toString() === args.amount.toString()) {
logger.debug('XCom: revertSendCoins matching pendingTX for remove...')
try {
@ -204,7 +208,10 @@ export class SendCoinsResolver {
linkedUserCommunityUuid: args.senderCommunityUuid,
linkedUserGradidoID: args.senderUserUuid,
})
logger.debug('XCom: settleSendCoins found pendingTX=', pendingTx?.toString())
logger.debug(
'XCom: settleSendCoins found pendingTX=',
pendingTx ? new PendingTransactionLoggingView(pendingTx) : 'null',
)
if (
pendingTx &&
pendingTx.amount.toString() === args.amount.toString() &&
@ -274,7 +281,10 @@ export class SendCoinsResolver {
linkedUserCommunityUuid: args.senderCommunityUuid,
linkedUserGradidoID: args.senderUserUuid,
})
logger.debug('XCom: revertSettledSendCoins found pendingTX=', pendingTx)
logger.debug(
'XCom: revertSettledSendCoins found pendingTX=',
pendingTx ? new PendingTransactionLoggingView(pendingTx) : 'null',
)
if (
pendingTx &&
pendingTx.amount.toString() === args.amount.toString() &&

View File

@ -89,7 +89,7 @@ export async function startAuthentication(
logger.debug(
`Authentication: received communityUUid for callbackFedCom:`,
fedComUuid,
fedComB,
new FederatedCommunityLoggingView(fedComB),
)
const callbackCom = await DbCommunity.findOneByOrFail({
foreign: true,

View File

@ -15,6 +15,10 @@ import { federationLogger as logger } from '@/server/logger'
import { getLastTransaction } from '@/graphql/util/getLastTransaction'
import { TRANSACTIONS_LOCK } from '@/graphql/util/TRANSACTIONS_LOCK'
import { CommunityLoggingView } from '@logging/CommunityLogging.view'
import { UserLoggingView } from '@logging/UserLogging.view'
import { PendingTransactionLoggingView } from '@logging/PendingTransactionLogging.view'
import { TransactionLoggingView } from '@logging/TransactionLogging.view'
export async function revertSettledReceiveTransaction(
homeCom: DbCommunity,
@ -30,7 +34,11 @@ export async function revertSettledReceiveTransaction(
logger.debug(`start Transaction for write-access...`)
try {
logger.info('X-Com: revertSettledReceiveTransaction:', homeCom, receiverUser, pendingTx)
logger.info('X-Com: revertSettledReceiveTransaction:', {
homeCom: new CommunityLoggingView(homeCom),
receiverUser: new UserLoggingView(receiverUser),
pendingTx: new PendingTransactionLoggingView(pendingTx),
})
// ensure that no other pendingTx with the same sender or recipient exists
const openSenderPendingTx = await DbPendingTransaction.count({
@ -68,6 +76,7 @@ export async function revertSettledReceiveTransaction(
pendingTx.balanceDate.toISOString(),
)
logger.debug(`GradidoID:`, lastTransaction?.userGradidoID, pendingTx.userGradidoID)
// todo: Data privacy: personal user data in log file?
logger.debug(`Name:`, lastTransaction?.userName, pendingTx.userName)
logger.debug(`amount:`, lastTransaction?.amount.toString(), pendingTx.amount.toString())
logger.debug(`memo:`, lastTransaction?.memo, pendingTx.memo)
@ -90,7 +99,10 @@ export async function revertSettledReceiveTransaction(
lastTransaction.linkedUserName === pendingTx.linkedUserName
) {
await queryRunner.manager.remove(dbTransaction, lastTransaction)
logger.debug(`X-Com: revert settlement receive Transaction removed:`, lastTransaction)
logger.debug(
`X-Com: revert settlement receive Transaction removed:`,
new TransactionLoggingView(lastTransaction),
)
// and mark the pendingTx in the pending_transactions table as reverted
pendingTx.state = PendingTransactionState.REVERTED
await queryRunner.manager.save(DbPendingTransaction, pendingTx)
@ -98,12 +110,11 @@ export async function revertSettledReceiveTransaction(
await queryRunner.commitTransaction()
logger.debug(`commit revert settlement recipient Transaction successful...`)
} else {
// TODO: if the last TX is not equivelant to pendingTX, the transactions must be corrected in EXPERT-MODE
throw new LogError(
`X-Com: missmatching transaction order for revert settlement!`,
lastTransaction,
pendingTx,
)
// TODO: if the last TX is not equivalent to pendingTX, the transactions must be corrected in EXPERT-MODE
throw new LogError(`X-Com: mismatching transaction order for revert settlement!`, {
lastTransaction: lastTransaction ? new TransactionLoggingView(lastTransaction) : 'null',
pendingTx: new PendingTransactionLoggingView(pendingTx),
})
}
/*

View File

@ -17,6 +17,10 @@ import { getLastTransaction } from '@/graphql/util/getLastTransaction'
import { TRANSACTIONS_LOCK } from '@/graphql/util/TRANSACTIONS_LOCK'
import { calculateRecipientBalance } from './calculateRecipientBalance'
import Decimal from 'decimal.js-light'
import { CommunityLoggingView } from '@logging/CommunityLogging.view'
import { UserLoggingView } from '@logging/UserLogging.view'
import { PendingTransactionLoggingView } from '@logging/PendingTransactionLogging.view'
import { TransactionLoggingView } from '@logging/TransactionLogging.view'
export async function settlePendingReceiveTransaction(
homeCom: DbCommunity,
@ -32,7 +36,11 @@ export async function settlePendingReceiveTransaction(
logger.debug(`start Transaction for write-access...`)
try {
logger.info('X-Com: settlePendingReceiveTransaction:', homeCom, receiverUser, pendingTx)
logger.info('X-Com: settlePendingReceiveTransaction:', {
homeCom: new CommunityLoggingView(homeCom),
receiverUser: new UserLoggingView(receiverUser),
pendingTx: new PendingTransactionLoggingView(pendingTx),
})
// ensure that no other pendingTx with the same sender or recipient exists
const openSenderPendingTx = await DbPendingTransaction.count({
@ -84,7 +92,7 @@ export async function settlePendingReceiveTransaction(
transactionReceive.previous = receiveBalance ? receiveBalance.lastTransactionId : null
transactionReceive.linkedTransactionId = pendingTx.linkedTransactionId
await queryRunner.manager.insert(dbTransaction, transactionReceive)
logger.debug(`receive Transaction inserted: ${dbTransaction}`)
logger.debug(`receive Transaction inserted: ${new TransactionLoggingView(transactionReceive)}`)
// and mark the pendingTx in the pending_transactions table as settled
pendingTx.state = PendingTransactionState.SETTLED

View File

@ -2,6 +2,8 @@ import { User as DbUser } from '@entity/User'
import { federationLogger as logger } from '@/server/logger'
import { SendCoinsArgs } from '../model/SendCoinsArgs'
import { UserLoggingView } from '@logging/UserLogging.view'
import { SendCoinsArgsLoggingView } from '../logger/SendCoinsArgsLogging.view'
export async function storeForeignUser(args: SendCoinsArgs): Promise<boolean> {
if (args.senderCommunityUuid !== null && args.senderUserUuid !== null) {
@ -34,7 +36,7 @@ export async function storeForeignUser(args: SendCoinsArgs): Promise<boolean> {
}
foreignUser.gradidoID = args.senderUserUuid
foreignUser = await DbUser.save(foreignUser)
logger.debug('X-Com: new foreignUser inserted:', foreignUser)
logger.debug('X-Com: new foreignUser inserted:', new UserLoggingView(foreignUser))
return true
} else if (
@ -43,14 +45,13 @@ export async function storeForeignUser(args: SendCoinsArgs): Promise<boolean> {
args.senderUserName.slice(args.senderUserName.indexOf(' '), args.senderUserName.length) ||
user.alias !== args.senderAlias
) {
logger.warn(
'X-Com: foreignUser still exists, but with different name or alias:',
user,
args,
)
logger.warn('X-Com: foreignUser still exists, but with different name or alias:', {
user: new UserLoggingView(user),
args: new SendCoinsArgsLoggingView(args),
})
return false
} else {
logger.debug('X-Com: foreignUser still exists...:', user)
logger.debug('X-Com: foreignUser still exists...:', new UserLoggingView(user))
return true
}
} catch (err) {

View File

@ -39,7 +39,10 @@ describe('PublicKeyResolver', () => {
homeCom.foreign = false
homeCom.apiVersion = '1_0'
homeCom.endPoint = 'endpoint-url'
homeCom.publicKey = Buffer.from('homeCommunity-publicKey')
homeCom.publicKey = Buffer.from(
'9f6dcd0d985cc7105cd71c3417d9c291b126c8ca90513197de02191f928ef713',
'hex',
)
await DbFederatedCommunity.insert(homeCom)
})
@ -47,7 +50,7 @@ describe('PublicKeyResolver', () => {
await expect(query({ query: getPublicKeyQuery })).resolves.toMatchObject({
data: {
getPublicKey: {
publicKey: expect.stringMatching('homeCommunity-publicKey'),
publicKey: '9f6dcd0d985cc7105cd71c3417d9c291b126c8ca90513197de02191f928ef713',
},
},
})