Merge branch 'master' into 2202-refactor-creations-query

This commit is contained in:
Moriz Wahl 2022-10-27 15:01:40 +02:00 committed by GitHub
commit 568a6cdd2c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 431 additions and 16 deletions

View File

@ -66,6 +66,9 @@ export class EventTransactionCreation extends EventBasicTx {}
export class EventTransactionReceive extends EventBasicTxX {}
export class EventTransactionReceiveRedeem extends EventBasicTxX {}
export class EventContributionCreate extends EventBasicCt {}
export class EventAdminContributionCreate extends EventBasicCt {}
export class EventAdminContributionDelete extends EventBasicCt {}
export class EventAdminContributionUpdate extends EventBasicCt {}
export class EventUserCreateContributionMessage extends EventBasicCtMsg {}
export class EventAdminCreateContributionMessage extends EventBasicCtMsg {}
export class EventContributionDelete extends EventBasicCt {}
@ -74,6 +77,14 @@ export class EventContributionConfirm extends EventBasicCtX {}
export class EventContributionDeny extends EventBasicCtX {}
export class EventContributionLinkDefine extends EventBasicCt {}
export class EventContributionLinkActivateRedeem extends EventBasicCt {}
export class EventDeleteUser extends EventBasicUserId {}
export class EventUndeleteUser extends EventBasicUserId {}
export class EventChangeUserRole extends EventBasicUserId {}
export class EventAdminUpdateContribution extends EventBasicCt {}
export class EventAdminDeleteContribution extends EventBasicCt {}
export class EventCreateContributionLink extends EventBasicCt {}
export class EventDeleteContributionLink extends EventBasicCt {}
export class EventUpdateContributionLink extends EventBasicCt {}
export class Event {
constructor()
@ -289,6 +300,27 @@ export class Event {
return this
}
public setEventAdminContributionCreate(ev: EventAdminContributionCreate): Event {
this.setByBasicCt(ev.userId, ev.contributionId, ev.amount)
this.type = EventProtocolType.ADMIN_CONTRIBUTION_CREATE
return this
}
public setEventAdminContributionDelete(ev: EventAdminContributionDelete): Event {
this.setByBasicCt(ev.userId, ev.contributionId, ev.amount)
this.type = EventProtocolType.ADMIN_CONTRIBUTION_DELETE
return this
}
public setEventAdminContributionUpdate(ev: EventAdminContributionUpdate): Event {
this.setByBasicCt(ev.userId, ev.contributionId, ev.amount)
this.type = EventProtocolType.ADMIN_CONTRIBUTION_UPDATE
return this
}
public setEventUserCreateContributionMessage(ev: EventUserCreateContributionMessage): Event {
this.setByBasicCtMsg(ev.userId, ev.contributionId, ev.amount, ev.messageId)
this.type = EventProtocolType.USER_CREATE_CONTRIBUTION_MESSAGE
@ -345,6 +377,62 @@ export class Event {
return this
}
public setEventDeleteUser(ev: EventDeleteUser): Event {
this.setByBasicUser(ev.userId)
this.type = EventProtocolType.DELETE_USER
return this
}
public setEventUndeleteUser(ev: EventUndeleteUser): Event {
this.setByBasicUser(ev.userId)
this.type = EventProtocolType.UNDELETE_USER
return this
}
public setEventChangeUserRole(ev: EventChangeUserRole): Event {
this.setByBasicUser(ev.userId)
this.type = EventProtocolType.CHANGE_USER_ROLE
return this
}
public setEventAdminUpdateContribution(ev: EventAdminUpdateContribution): Event {
this.setByBasicCt(ev.userId, ev.contributionId, ev.amount)
this.type = EventProtocolType.ADMIN_UPDATE_CONTRIBUTION
return this
}
public setEventAdminDeleteContribution(ev: EventAdminDeleteContribution): Event {
this.setByBasicCt(ev.userId, ev.contributionId, ev.amount)
this.type = EventProtocolType.ADMIN_DELETE_CONTRIBUTION
return this
}
public setEventCreateContributionLink(ev: EventCreateContributionLink): Event {
this.setByBasicCt(ev.userId, ev.contributionId, ev.amount)
this.type = EventProtocolType.CREATE_CONTRIBUTION_LINK
return this
}
public setEventDeleteContributionLink(ev: EventDeleteContributionLink): Event {
this.setByBasicCt(ev.userId, ev.contributionId, ev.amount)
this.type = EventProtocolType.DELETE_CONTRIBUTION_LINK
return this
}
public setEventUpdateContributionLink(ev: EventUpdateContributionLink): Event {
this.setByBasicCt(ev.userId, ev.contributionId, ev.amount)
this.type = EventProtocolType.UPDATE_CONTRIBUTION_LINK
return this
}
setByBasicUser(userId: number): Event {
this.setEventBasic()
this.userId = userId

View File

@ -33,6 +33,17 @@ export enum EventProtocolType {
CONTRIBUTION_LINK_ACTIVATE_REDEEM = 'CONTRIBUTION_LINK_ACTIVATE_REDEEM',
CONTRIBUTION_DELETE = 'CONTRIBUTION_DELETE',
CONTRIBUTION_UPDATE = 'CONTRIBUTION_UPDATE',
ADMIN_CONTRIBUTION_CREATE = 'ADMIN_CONTRIBUTION_CREATE',
ADMIN_CONTRIBUTION_DELETE = 'ADMIN_CONTRIBUTION_DELETE',
ADMIN_CONTRIBUTION_UPDATE = 'ADMIN_CONTRIBUTION_UPDATE',
USER_CREATE_CONTRIBUTION_MESSAGE = 'USER_CREATE_CONTRIBUTION_MESSAGE',
ADMIN_CREATE_CONTRIBUTION_MESSAGE = 'ADMIN_CREATE_CONTRIBUTION_MESSAGE',
DELETE_USER = 'DELETE_USER',
UNDELETE_USER = 'UNDELETE_USER',
CHANGE_USER_ROLE = 'CHANGE_USER_ROLE',
ADMIN_UPDATE_CONTRIBUTION = 'ADMIN_UPDATE_CONTRIBUTION',
ADMIN_DELETE_CONTRIBUTION = 'ADMIN_DELETE_CONTRIBUTION',
CREATE_CONTRIBUTION_LINK = 'CREATE_CONTRIBUTION_LINK',
DELETE_CONTRIBUTION_LINK = 'DELETE_CONTRIBUTION_LINK',
UPDATE_CONTRIBUTION_LINK = 'UPDATE_CONTRIBUTION_LINK',
}

View File

@ -42,6 +42,9 @@ import { Contribution } from '@entity/Contribution'
import { Transaction as DbTransaction } from '@entity/Transaction'
import { ContributionLink as DbContributionLink } from '@entity/ContributionLink'
import { sendContributionConfirmedEmail } from '@/mailer/sendContributionConfirmedEmail'
import { EventProtocol } from '@entity/EventProtocol'
import { EventProtocolType } from '@/event/EventProtocolType'
import { logger } from '@test/testSetup'
// mock account activation email to avoid console spam
jest.mock('@/mailer/sendAccountActivationEmail', () => {
@ -144,6 +147,10 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(`Could not find user with userId: ${admin.id + 1}`)
})
})
describe('change role with success', () => {
@ -196,6 +203,9 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('Administrator can not change his own role!')
})
})
describe('user has already role to be set', () => {
@ -213,6 +223,10 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('User is already admin!')
})
})
describe('to usual user', () => {
@ -229,6 +243,10 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('User is already a usual user!')
})
})
})
})
@ -297,6 +315,10 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(`Could not find user with userId: ${admin.id + 1}`)
})
})
describe('delete self', () => {
@ -309,6 +331,10 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('Moderator can not delete his own account!')
})
})
describe('delete with success', () => {
@ -338,6 +364,10 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(`Could not find user with userId: ${user.id}`)
})
})
})
})
@ -405,6 +435,10 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(`Could not find user with userId: ${admin.id + 1}`)
})
})
describe('user to undelete is not deleted', () => {
@ -422,6 +456,10 @@ describe('AdminResolver', () => {
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('User is not deleted')
})
describe('undelete deleted user', () => {
beforeAll(async () => {
await mutate({ mutation: deleteUser, variables: { userId: user.id } })
@ -909,6 +947,12 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'Could not find user with email: bibi@bloxberg.de',
)
})
})
describe('user to create for is deleted', () => {
@ -928,6 +972,12 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'This user was deleted. Cannot create a contribution.',
)
})
})
describe('user to create for has email not confirmed', () => {
@ -947,6 +997,12 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'Contribution could not be saved, Email is not activated',
)
})
})
describe('valid user to create for', () => {
@ -967,6 +1023,13 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'No information for available creations with the given creationDate=',
'Invalid Date',
)
})
})
describe('date of creation is four months ago', () => {
@ -987,6 +1050,13 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'No information for available creations with the given creationDate=',
variables.creationDate,
)
})
})
describe('date of creation is in the future', () => {
@ -1007,6 +1077,13 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'No information for available creations with the given creationDate=',
variables.creationDate,
)
})
})
describe('amount of creation is too high', () => {
@ -1024,6 +1101,12 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'The amount (2000 GDD) to be created exceeds the amount (1000 GDD) still available for this month.',
)
})
})
describe('creation is valid', () => {
@ -1039,6 +1122,15 @@ describe('AdminResolver', () => {
}),
)
})
it('stores the admin create contribution event in the database', async () => {
await expect(EventProtocol.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventProtocolType.ADMIN_CONTRIBUTION_CREATE,
userId: admin.id,
}),
)
})
})
describe('second creation surpasses the available amount ', () => {
@ -1056,6 +1148,12 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'The amount (1000 GDD) to be created exceeds the amount (800 GDD) still available for this month.',
)
})
})
})
})
@ -1134,6 +1232,12 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'Could not find UserContact with email: bob@baumeister.de',
)
})
})
describe('user for creation to update is deleted', () => {
@ -1155,6 +1259,10 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('User was deleted (stephen@hawking.uk)')
})
})
describe('creation does not exist', () => {
@ -1176,6 +1284,10 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('No contribution found to given id.')
})
})
describe('user email does not match creation user', () => {
@ -1188,7 +1300,9 @@ describe('AdminResolver', () => {
email: 'bibi@bloxberg.de',
amount: new Decimal(300),
memo: 'Danke Bibi!',
creationDate: new Date().toString(),
creationDate: creation
? creation.contributionDate.toString()
: new Date().toString(),
},
}),
).resolves.toEqual(
@ -1201,11 +1315,17 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'user of the pending contribution and send user does not correspond',
)
})
})
describe('creation update is not valid', () => {
// as this test has not clearly defined that date, it is a false positive
it.skip('throws an error', async () => {
it('throws an error', async () => {
await expect(
mutate({
mutation: adminUpdateContribution,
@ -1214,24 +1334,32 @@ describe('AdminResolver', () => {
email: 'peter@lustig.de',
amount: new Decimal(1900),
memo: 'Danke Peter!',
creationDate: new Date().toString(),
creationDate: creation
? creation.contributionDate.toString()
: new Date().toString(),
},
}),
).resolves.toEqual(
expect.objectContaining({
errors: [
new GraphQLError(
'The amount (1900 GDD) to be created exceeds the amount (500 GDD) still available for this month.',
'The amount (1900 GDD) to be created exceeds the amount (1000 GDD) still available for this month.',
),
],
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'The amount (1900 GDD) to be created exceeds the amount (1000 GDD) still available for this month.',
)
})
})
describe('creation update is successful changing month', () => {
describe.skip('creation update is successful changing month', () => {
// skipped as changing the month is currently disable
it.skip('returns update creation object', async () => {
it('returns update creation object', async () => {
await expect(
mutate({
mutation: adminUpdateContribution,
@ -1240,7 +1368,9 @@ describe('AdminResolver', () => {
email: 'peter@lustig.de',
amount: new Decimal(300),
memo: 'Danke Peter!',
creationDate: new Date().toString(),
creationDate: creation
? creation.contributionDate.toString()
: new Date().toString(),
},
}),
).resolves.toEqual(
@ -1250,17 +1380,26 @@ describe('AdminResolver', () => {
date: expect.any(String),
memo: 'Danke Peter!',
amount: '300',
creation: ['1000', '1000', '200'],
creation: ['1000', '700', '500'],
},
},
}),
)
})
it('stores the admin update contribution event in the database', async () => {
await expect(EventProtocol.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventProtocolType.ADMIN_CONTRIBUTION_UPDATE,
userId: admin.id,
}),
)
})
})
describe('creation update is successful without changing month', () => {
// actually this mutation IS changing the month
it.skip('returns update creation object', async () => {
it('returns update creation object', async () => {
await expect(
mutate({
mutation: adminUpdateContribution,
@ -1269,7 +1408,9 @@ describe('AdminResolver', () => {
email: 'peter@lustig.de',
amount: new Decimal(200),
memo: 'Das war leider zu Viel!',
creationDate: new Date().toString(),
creationDate: creation
? creation.contributionDate.toString()
: new Date().toString(),
},
}),
).resolves.toEqual(
@ -1279,12 +1420,21 @@ describe('AdminResolver', () => {
date: expect.any(String),
memo: 'Das war leider zu Viel!',
amount: '200',
creation: ['1000', '1000', '300'],
creation: ['1000', '800', '500'],
},
},
}),
)
})
it('stores the admin update contribution event in the database', async () => {
await expect(EventProtocol.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventProtocolType.ADMIN_CONTRIBUTION_UPDATE,
userId: admin.id,
}),
)
})
})
})
@ -1304,10 +1454,10 @@ describe('AdminResolver', () => {
lastName: 'Lustig',
email: 'peter@lustig.de',
date: expect.any(String),
memo: 'Herzlich Willkommen bei Gradido!',
amount: '400',
memo: 'Das war leider zu Viel!',
amount: '200',
moderator: admin.id,
creation: ['1000', '600', '500'],
creation: ['1000', '800', '500'],
},
{
id: expect.any(Number),
@ -1318,7 +1468,7 @@ describe('AdminResolver', () => {
memo: 'Grundeinkommen',
amount: '500',
moderator: admin.id,
creation: ['1000', '600', '500'],
creation: ['1000', '800', '500'],
},
{
id: expect.any(Number),
@ -1365,6 +1515,10 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('Contribution not found for given id: -1')
})
})
describe('admin deletes own user contribution', () => {
@ -1414,6 +1568,15 @@ describe('AdminResolver', () => {
}),
)
})
it('stores the admin delete contribution event in the database', async () => {
await expect(EventProtocol.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventProtocolType.ADMIN_CONTRIBUTION_DELETE,
userId: admin.id,
}),
)
})
})
})
@ -1433,6 +1596,10 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('Contribution not found for given id: -1')
})
})
describe('confirm own creation', () => {
@ -1460,6 +1627,10 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('Moderator can not confirm own contribution')
})
})
describe('confirm creation for other user', () => {
@ -1488,6 +1659,14 @@ describe('AdminResolver', () => {
)
})
it('stores the contribution confirm event in the database', async () => {
await expect(EventProtocol.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventProtocolType.CONTRIBUTION_CONFIRM,
}),
)
})
it('creates a transaction', async () => {
const transaction = await DbTransaction.find()
expect(transaction[0].amount.toString()).toBe('450')
@ -1512,6 +1691,14 @@ describe('AdminResolver', () => {
}),
)
})
it('stores the send confirmation email event in the database', async () => {
await expect(EventProtocol.find()).resolves.toContainEqual(
expect.objectContaining({
type: EventProtocolType.SEND_CONFIRMATION_EMAIL,
}),
)
})
})
describe('confirm two creations one after the other quickly', () => {
@ -2052,6 +2239,12 @@ describe('AdminResolver', () => {
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'Start-Date is not initialized. A Start-Date must be set!',
)
})
it('returns an error if missing endDate', async () => {
await expect(
mutate({
@ -2068,6 +2261,12 @@ describe('AdminResolver', () => {
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'End-Date is not initialized. An End-Date must be set!',
)
})
it('returns an error if endDate is before startDate', async () => {
await expect(
mutate({
@ -2087,6 +2286,12 @@ describe('AdminResolver', () => {
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
`The value of validFrom must before or equals the validTo!`,
)
})
it('returns an error if name is an empty string', async () => {
await expect(
mutate({
@ -2103,6 +2308,10 @@ describe('AdminResolver', () => {
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('The name must be initialized!')
})
it('returns an error if name is shorter than 5 characters', async () => {
await expect(
mutate({
@ -2123,6 +2332,12 @@ describe('AdminResolver', () => {
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
`The value of 'name' with a length of 3 did not fulfill the requested bounderies min=5 and max=100`,
)
})
it('returns an error if name is longer than 100 characters', async () => {
await expect(
mutate({
@ -2143,6 +2358,12 @@ describe('AdminResolver', () => {
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
`The value of 'name' with a length of 101 did not fulfill the requested bounderies min=5 and max=100`,
)
})
it('returns an error if memo is an empty string', async () => {
await expect(
mutate({
@ -2159,6 +2380,10 @@ describe('AdminResolver', () => {
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('The memo must be initialized!')
})
it('returns an error if memo is shorter than 5 characters', async () => {
await expect(
mutate({
@ -2179,6 +2404,12 @@ describe('AdminResolver', () => {
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
`The value of 'memo' with a length of 3 did not fulfill the requested bounderies min=5 and max=255`,
)
})
it('returns an error if memo is longer than 255 characters', async () => {
await expect(
mutate({
@ -2199,6 +2430,12 @@ describe('AdminResolver', () => {
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
`The value of 'memo' with a length of 256 did not fulfill the requested bounderies min=5 and max=255`,
)
})
it('returns an error if amount is not positive', async () => {
await expect(
mutate({
@ -2216,6 +2453,12 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith(
'The amount=0 must be initialized with a positiv value!',
)
})
})
describe('listContributionLinks', () => {
@ -2271,6 +2514,10 @@ describe('AdminResolver', () => {
})
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('Contribution Link not found to given id: -1')
})
describe('valid id', () => {
let linkId: number
beforeAll(async () => {
@ -2336,6 +2583,10 @@ describe('AdminResolver', () => {
}),
)
})
it('logs the error thrown', () => {
expect(logger.error).toBeCalledWith('Contribution Link not found to given id: -1')
})
})
describe('valid id', () => {

View File

@ -64,6 +64,15 @@ import { ContributionMessageType } from '@enum/MessageType'
import { ContributionMessage } from '@model/ContributionMessage'
import { sendContributionConfirmedEmail } from '@/mailer/sendContributionConfirmedEmail'
import { sendAddedContributionMessageEmail } from '@/mailer/sendAddedContributionMessageEmail'
import { eventProtocol } from '@/event/EventProtocolEmitter'
import {
Event,
EventAdminContributionCreate,
EventAdminContributionDelete,
EventAdminContributionUpdate,
EventContributionConfirm,
EventSendConfirmationEmail,
} from '@/event/Event'
import { ContributionListResult } from '../model/Contribution'
// const EMAIL_OPT_IN_REGISTER = 1
@ -145,11 +154,13 @@ export class AdminResolver {
const user = await dbUser.findOne({ id: userId })
// user exists ?
if (!user) {
logger.error(`Could not find user with userId: ${userId}`)
throw new Error(`Could not find user with userId: ${userId}`)
}
// administrator user changes own role?
const moderatorUser = getUser(context)
if (moderatorUser.id === userId) {
logger.error('Administrator can not change his own role!')
throw new Error('Administrator can not change his own role!')
}
// change isAdmin
@ -158,6 +169,7 @@ export class AdminResolver {
if (isAdmin === true) {
user.isAdmin = new Date()
} else {
logger.error('User is already a usual user!')
throw new Error('User is already a usual user!')
}
break
@ -165,6 +177,7 @@ export class AdminResolver {
if (isAdmin === false) {
user.isAdmin = null
} else {
logger.error('User is already admin!')
throw new Error('User is already admin!')
}
break
@ -183,11 +196,13 @@ export class AdminResolver {
const user = await dbUser.findOne({ id: userId })
// user exists ?
if (!user) {
logger.error(`Could not find user with userId: ${userId}`)
throw new Error(`Could not find user with userId: ${userId}`)
}
// moderator user disabled own account?
const moderatorUser = getUser(context)
if (moderatorUser.id === userId) {
logger.error('Moderator can not delete his own account!')
throw new Error('Moderator can not delete his own account!')
}
// soft-delete user
@ -201,9 +216,11 @@ export class AdminResolver {
async unDeleteUser(@Arg('userId', () => Int) userId: number): Promise<Date | null> {
const user = await dbUser.findOne({ id: userId }, { withDeleted: true })
if (!user) {
logger.error(`Could not find user with userId: ${userId}`)
throw new Error(`Could not find user with userId: ${userId}`)
}
if (!user.deletedAt) {
logger.error('User is not deleted')
throw new Error('User is not deleted')
}
await user.recover()
@ -240,6 +257,8 @@ export class AdminResolver {
logger.error('Contribution could not be saved, Email is not activated')
throw new Error('Contribution could not be saved, Email is not activated')
}
const event = new Event()
const moderator = getUser(context)
logger.trace('moderator: ', moderator.id)
const creations = await getUserCreation(emailContact.userId)
@ -258,7 +277,17 @@ export class AdminResolver {
contribution.contributionStatus = ContributionStatus.PENDING
logger.trace('contribution to save', contribution)
await DbContribution.save(contribution)
const eventAdminCreateContribution = new EventAdminContributionCreate()
eventAdminCreateContribution.userId = moderator.id
eventAdminCreateContribution.amount = amount
eventAdminCreateContribution.contributionId = contribution.id
await eventProtocol.writeEvent(
event.setEventAdminContributionCreate(eventAdminCreateContribution),
)
return getUserCreation(emailContact.userId)
}
@ -319,7 +348,6 @@ export class AdminResolver {
const contributionToUpdate = await DbContribution.findOne({
where: { id, confirmedAt: IsNull() },
})
if (!contributionToUpdate) {
logger.error('No contribution found to given id.')
throw new Error('No contribution found to given id.')
@ -337,6 +365,7 @@ export class AdminResolver {
const creationDateObj = new Date(creationDate)
let creations = await getUserCreation(user.id)
if (contributionToUpdate.contributionDate.getMonth() === creationDateObj.getMonth()) {
creations = updateCreations(creations, contributionToUpdate)
} else {
@ -353,6 +382,7 @@ export class AdminResolver {
contributionToUpdate.contributionStatus = ContributionStatus.PENDING
await DbContribution.save(contributionToUpdate)
const result = new AdminUpdateContribution()
result.amount = amount
result.memo = contributionToUpdate.memo
@ -360,6 +390,15 @@ export class AdminResolver {
result.creation = await getUserCreation(user.id)
const event = new Event()
const eventAdminContributionUpdate = new EventAdminContributionUpdate()
eventAdminContributionUpdate.userId = user.id
eventAdminContributionUpdate.amount = amount
eventAdminContributionUpdate.contributionId = contributionToUpdate.id
await eventProtocol.writeEvent(
event.setEventAdminContributionUpdate(eventAdminContributionUpdate),
)
return result
}
@ -420,6 +459,16 @@ export class AdminResolver {
contribution.deletedBy = moderator.id
await contribution.save()
const res = await contribution.softRemove()
const event = new Event()
const eventAdminContributionDelete = new EventAdminContributionDelete()
eventAdminContributionDelete.userId = contribution.userId
eventAdminContributionDelete.amount = contribution.amount
eventAdminContributionDelete.contributionId = contribution.id
await eventProtocol.writeEvent(
event.setEventAdminContributionDelete(eventAdminContributionDelete),
)
return !!res
}
@ -515,6 +564,13 @@ export class AdminResolver {
} finally {
await queryRunner.release()
}
const event = new Event()
const eventContributionConfirm = new EventContributionConfirm()
eventContributionConfirm.userId = user.id
eventContributionConfirm.amount = contribution.amount
eventContributionConfirm.contributionId = contribution.id
await eventProtocol.writeEvent(event.setEventContributionConfirm(eventContributionConfirm))
return true
}
@ -576,6 +632,13 @@ export class AdminResolver {
// In case EMails are disabled log the activation link for the user
if (!emailSent) {
logger.info(`Account confirmation link: ${activationLink}`)
} else {
const event = new Event()
const eventSendConfirmationEmail = new EventSendConfirmationEmail()
eventSendConfirmationEmail.userId = user.id
await eventProtocol.writeEvent(
event.setEventSendConfirmationEmail(eventSendConfirmationEmail),
)
}
return true
@ -768,9 +831,11 @@ export class AdminResolver {
relations: ['user'],
})
if (!contribution) {
logger.error('Contribution not found')
throw new Error('Contribution not found')
}
if (contribution.userId === user.id) {
logger.error('Admin can not answer on own contribution')
throw new Error('Admin can not answer on own contribution')
}
if (!contribution.user.emailContact) {