mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
Merge pull request #1521 from gradido/user_soft_delete_backend
feature: Soft-Delete for users (backend)
This commit is contained in:
commit
a45a6961cb
@ -23,6 +23,7 @@ import { calculateDecay } from '../../util/decay'
|
||||
import { AdminPendingCreation } from '@entity/AdminPendingCreation'
|
||||
import { hasElopageBuys } from '../../util/hasElopageBuys'
|
||||
import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
|
||||
import { User } from '@entity/User'
|
||||
|
||||
// const EMAIL_OPT_IN_REGISTER = 1
|
||||
// const EMAIL_OPT_UNKNOWN = 3 // elopage?
|
||||
@ -82,8 +83,13 @@ export class AdminResolver {
|
||||
async createPendingCreation(
|
||||
@Args() { email, amount, memo, creationDate, moderator }: CreatePendingCreationArgs,
|
||||
): Promise<number[]> {
|
||||
const userRepository = getCustomRepository(UserRepository)
|
||||
const user = await userRepository.findByEmail(email)
|
||||
const user = await User.findOne({ email }, { withDeleted: true })
|
||||
if (!user) {
|
||||
throw new Error(`Could not find user with email: ${email}`)
|
||||
}
|
||||
if (user.deletedAt) {
|
||||
throw new Error('This user was deleted. Cannot make a creation.')
|
||||
}
|
||||
if (!user.emailChecked) {
|
||||
throw new Error('Creation could not be saved, Email is not activated')
|
||||
}
|
||||
@ -134,8 +140,13 @@ export class AdminResolver {
|
||||
async updatePendingCreation(
|
||||
@Args() { id, email, amount, memo, creationDate, moderator }: UpdatePendingCreationArgs,
|
||||
): Promise<UpdatePendingCreation> {
|
||||
const userRepository = getCustomRepository(UserRepository)
|
||||
const user = await userRepository.findByEmail(email)
|
||||
const user = await User.findOne({ email }, { withDeleted: true })
|
||||
if (!user) {
|
||||
throw new Error(`Could not find user with email: ${email}`)
|
||||
}
|
||||
if (user.deletedAt) {
|
||||
throw new Error(`User was deleted (${email})`)
|
||||
}
|
||||
|
||||
const pendingCreationToUpdate = await AdminPendingCreation.findOneOrFail({ id })
|
||||
|
||||
|
||||
@ -272,16 +272,6 @@ async function addUserTransaction(
|
||||
})
|
||||
}
|
||||
|
||||
async function getPublicKey(email: string): Promise<string | null> {
|
||||
const user = await dbUser.findOne({ email: email })
|
||||
// User not found
|
||||
if (!user) {
|
||||
return null
|
||||
}
|
||||
|
||||
return user.pubKey.toString('hex')
|
||||
}
|
||||
|
||||
@Resolver()
|
||||
export class TransactionResolver {
|
||||
@Authorized([RIGHTS.TRANSACTION_LIST])
|
||||
@ -301,7 +291,7 @@ export class TransactionResolver {
|
||||
const userRepository = getCustomRepository(UserRepository)
|
||||
let userEntity: dbUser | undefined
|
||||
if (userId) {
|
||||
userEntity = await userRepository.findOneOrFail({ id: userId })
|
||||
userEntity = await userRepository.findOneOrFail({ id: userId }, { withDeleted: true })
|
||||
} else {
|
||||
userEntity = await userRepository.findByPubkeyHex(context.pubKey)
|
||||
}
|
||||
@ -357,18 +347,15 @@ export class TransactionResolver {
|
||||
|
||||
// validate recipient user
|
||||
// TODO: the detour over the public key is unnecessary
|
||||
const recipiantPublicKey = await getPublicKey(email)
|
||||
if (!recipiantPublicKey) {
|
||||
const recipientUser = await dbUser.findOne({ email: email }, { withDeleted: true })
|
||||
if (!recipientUser) {
|
||||
throw new Error('recipient not known')
|
||||
}
|
||||
if (!isHexPublicKey(recipiantPublicKey)) {
|
||||
throw new Error('invalid recipiant public key')
|
||||
if (recipientUser.deletedAt) {
|
||||
throw new Error('The recipient account was deleted')
|
||||
}
|
||||
const recipiantUser = await userRepository.findByPubkeyHex(recipiantPublicKey)
|
||||
if (!recipiantUser) {
|
||||
throw new Error('Cannot find recipiant user by local send coins transaction')
|
||||
} else if (recipiantUser.deletedAt) {
|
||||
throw new Error('recipiant user account is disabled')
|
||||
if (!isHexPublicKey(recipientUser.pubKey.toString('hex'))) {
|
||||
throw new Error('invalid recipient public key')
|
||||
}
|
||||
|
||||
// validate amount
|
||||
@ -405,7 +392,7 @@ export class TransactionResolver {
|
||||
|
||||
// Insert Transaction: recipient + amount
|
||||
const recipiantUserTransactionBalance = await addUserTransaction(
|
||||
recipiantUser,
|
||||
recipientUser,
|
||||
transaction,
|
||||
centAmount,
|
||||
queryRunner,
|
||||
@ -421,7 +408,7 @@ export class TransactionResolver {
|
||||
|
||||
// Update Balance: recipiant + amount
|
||||
const recipiantStateBalance = await updateStateBalance(
|
||||
recipiantUser,
|
||||
recipientUser,
|
||||
centAmount,
|
||||
transaction.received,
|
||||
queryRunner,
|
||||
@ -439,8 +426,8 @@ export class TransactionResolver {
|
||||
transactionSendCoin.transactionId = transaction.id
|
||||
transactionSendCoin.userId = senderUser.id
|
||||
transactionSendCoin.senderPublic = senderUser.pubKey
|
||||
transactionSendCoin.recipiantUserId = recipiantUser.id
|
||||
transactionSendCoin.recipiantPublic = Buffer.from(recipiantPublicKey, 'hex')
|
||||
transactionSendCoin.recipiantUserId = recipientUser.id
|
||||
transactionSendCoin.recipiantPublic = recipientUser.pubKey
|
||||
transactionSendCoin.amount = centAmount
|
||||
transactionSendCoin.senderFinalBalance = senderStateBalance.amount
|
||||
await queryRunner.manager.save(transactionSendCoin).catch((error) => {
|
||||
@ -474,9 +461,9 @@ export class TransactionResolver {
|
||||
await sendTransactionReceivedEmail({
|
||||
senderFirstName: senderUser.firstName,
|
||||
senderLastName: senderUser.lastName,
|
||||
recipientFirstName: recipiantUser.firstName,
|
||||
recipientLastName: recipiantUser.lastName,
|
||||
email: recipiantUser.email,
|
||||
recipientFirstName: recipientUser.firstName,
|
||||
recipientLastName: recipientUser.lastName,
|
||||
email: recipientUser.email,
|
||||
amount,
|
||||
memo,
|
||||
})
|
||||
|
||||
@ -250,9 +250,12 @@ export class UserResolver {
|
||||
@Ctx() context: any,
|
||||
): Promise<User> {
|
||||
email = email.trim().toLowerCase()
|
||||
const dbUser = await DbUser.findOneOrFail({ email }).catch(() => {
|
||||
const dbUser = await DbUser.findOneOrFail({ email }, { withDeleted: true }).catch(() => {
|
||||
throw new Error('No user with this credentials')
|
||||
})
|
||||
if (dbUser.deletedAt) {
|
||||
throw new Error('This user was permanently disabled. Contact support for questions.')
|
||||
}
|
||||
if (!dbUser.emailChecked) {
|
||||
throw new Error('User email not validated')
|
||||
}
|
||||
@ -335,9 +338,9 @@ export class UserResolver {
|
||||
|
||||
// Validate email unique
|
||||
// TODO: i can register an email in upper/lower case twice
|
||||
const userRepository = getCustomRepository(UserRepository)
|
||||
const usersFound = await userRepository.count({ email })
|
||||
if (usersFound !== 0) {
|
||||
// TODO we cannot use repository.count(), since it does not allow to specify if you want to include the soft deletes
|
||||
const userFound = await DbUser.findOne({ email }, { withDeleted: true })
|
||||
if (userFound) {
|
||||
// TODO: this is unsecure, but the current implementation of the login server. This way it can be queried if the user with given EMail is existent.
|
||||
throw new Error(`User already exists.`)
|
||||
}
|
||||
|
||||
@ -14,10 +14,6 @@ export class UserRepository extends Repository<User> {
|
||||
return await this.findByPubkeyHex(pubKeyString)
|
||||
}
|
||||
|
||||
async findByEmail(email: string): Promise<User> {
|
||||
return this.createQueryBuilder('user').where('user.email = :email', { email }).getOneOrFail()
|
||||
}
|
||||
|
||||
async getUsersIndiced(userIds: number[]): Promise<User[]> {
|
||||
if (!userIds.length) return []
|
||||
const users = await this.createQueryBuilder('user')
|
||||
@ -33,6 +29,7 @@ export class UserRepository extends Repository<User> {
|
||||
|
||||
async findBySearchCriteria(searchCriteria: string): Promise<User[]> {
|
||||
return await this.createQueryBuilder('user')
|
||||
.withDeleted()
|
||||
.where(
|
||||
'user.firstName like :name or user.lastName like :lastName or user.email like :email',
|
||||
{
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user