mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
move sendActivationEmail mutation from user to admin resolver
This commit is contained in:
parent
1e3300ad5a
commit
9da2047e8c
@ -34,6 +34,8 @@ import { Decay } from '@model/Decay'
|
|||||||
import Paginated from '@arg/Paginated'
|
import Paginated from '@arg/Paginated'
|
||||||
import { Order } from '@enum/Order'
|
import { Order } from '@enum/Order'
|
||||||
import { communityUser } from '@/util/communityUser'
|
import { communityUser } from '@/util/communityUser'
|
||||||
|
import { checkExistingOptInCode, activationLink } from './UserResolver'
|
||||||
|
import { sendAccountActivationEmail } from '@/mailer/sendAccountActivationEmail'
|
||||||
|
|
||||||
// const EMAIL_OPT_IN_REGISTER = 1
|
// const EMAIL_OPT_IN_REGISTER = 1
|
||||||
// const EMAIL_OPT_UNKNOWN = 3 // elopage?
|
// const EMAIL_OPT_UNKNOWN = 3 // elopage?
|
||||||
@ -369,6 +371,40 @@ export class AdminResolver {
|
|||||||
const user = await dbUser.findOneOrFail({ id: userId })
|
const user = await dbUser.findOneOrFail({ id: userId })
|
||||||
return userTransactions.map((t) => new Transaction(t, new User(user), communityUser))
|
return userTransactions.map((t) => new Transaction(t, new User(user), communityUser))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Authorized([RIGHTS.SEND_ACTIVATION_EMAIL])
|
||||||
|
@Mutation(() => Boolean)
|
||||||
|
async sendActivationEmail(@Arg('email') email: string): Promise<boolean> {
|
||||||
|
email = email.trim().toLowerCase()
|
||||||
|
const user = await dbUser.findOneOrFail({ email: email })
|
||||||
|
|
||||||
|
// can be both types: REGISTER and RESET_PASSWORD
|
||||||
|
let optInCode = await LoginEmailOptIn.findOne({
|
||||||
|
userId: user.id,
|
||||||
|
})
|
||||||
|
|
||||||
|
optInCode = checkExistingOptInCode(optInCode, user.id)
|
||||||
|
// keep the optin type (when newly created is is REGISTER)
|
||||||
|
await LoginEmailOptIn.save(optInCode)
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
|
const emailSent = await sendAccountActivationEmail({
|
||||||
|
link: activationLink(optInCode),
|
||||||
|
firstName: user.firstName,
|
||||||
|
lastName: user.lastName,
|
||||||
|
email,
|
||||||
|
})
|
||||||
|
|
||||||
|
/* uncomment this, when you need the activation link on the console
|
||||||
|
// In case EMails are disabled log the activation link for the user
|
||||||
|
if (!emailSent) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.log(`Account confirmation link: ${activationLink}`)
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CreationMap {
|
interface CreationMap {
|
||||||
|
|||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
import { Resolver, Query, Args, Arg, Authorized, Ctx, UseMiddleware, Mutation } from 'type-graphql'
|
import { Resolver, Query, Args, Arg, Authorized, Ctx, UseMiddleware, Mutation } from 'type-graphql'
|
||||||
import { getConnection, getCustomRepository, QueryRunner } from '@dbTools/typeorm'
|
import { getConnection, getCustomRepository } from '@dbTools/typeorm'
|
||||||
import CONFIG from '@/config'
|
import CONFIG from '@/config'
|
||||||
import { User } from '@model/User'
|
import { User } from '@model/User'
|
||||||
import { User as DbUser } from '@entity/User'
|
import { User as DbUser } from '@entity/User'
|
||||||
@ -155,35 +155,29 @@ const newEmailOptIn = (userId: number): LoginEmailOptIn => {
|
|||||||
return emailOptIn
|
return emailOptIn
|
||||||
}
|
}
|
||||||
|
|
||||||
const createEmailOptIn = async (
|
// needed by AdminResolver
|
||||||
|
// checks if given code exists and can be resent
|
||||||
|
// if optIn does not exits, it is created
|
||||||
|
export const checkExistingOptInCode = (
|
||||||
|
optInCode: LoginEmailOptIn | undefined,
|
||||||
userId: number,
|
userId: number,
|
||||||
queryRunner: QueryRunner,
|
): LoginEmailOptIn => {
|
||||||
): Promise<LoginEmailOptIn> => {
|
if (optInCode) {
|
||||||
let emailOptIn = await LoginEmailOptIn.findOne({
|
if (!canResendOptIn(optInCode)) {
|
||||||
userId,
|
|
||||||
emailOptInTypeId: OptInType.EMAIL_OPT_IN_REGISTER,
|
|
||||||
})
|
|
||||||
|
|
||||||
if (emailOptIn) {
|
|
||||||
if (isOptInValid(emailOptIn)) {
|
|
||||||
throw new Error(
|
throw new Error(
|
||||||
`email already sent less than ${printTimeDuration(CONFIG.EMAIL_CODE_REQUEST_TIME)} ago`,
|
`email already sent less than $(printTimeDuration(CONFIG.EMAIL_CODE_REQUEST_TIME)} minutes ago`,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
emailOptIn.updatedAt = new Date()
|
optInCode.updatedAt = new Date()
|
||||||
emailOptIn.resendCount++
|
optInCode.resendCount++
|
||||||
} else {
|
} else {
|
||||||
emailOptIn = new LoginEmailOptIn()
|
optInCode = newEmailOptIn(userId)
|
||||||
emailOptIn.verificationCode = random(64)
|
|
||||||
emailOptIn.userId = userId
|
|
||||||
emailOptIn.emailOptInTypeId = OptInType.EMAIL_OPT_IN_REGISTER
|
|
||||||
}
|
}
|
||||||
await queryRunner.manager.save(emailOptIn).catch((error) => {
|
return optInCode
|
||||||
// eslint-disable-next-line no-console
|
}
|
||||||
console.log('Error while saving emailOptIn', error)
|
|
||||||
throw new Error('error saving email opt in')
|
export const activationLink = (optInCode: LoginEmailOptIn): string => {
|
||||||
})
|
return CONFIG.EMAIL_LINK_SETPASSWORD.replace(/{optin}/g, optInCode.verificationCode.toString())
|
||||||
return emailOptIn
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Resolver()
|
@Resolver()
|
||||||
@ -388,50 +382,6 @@ export class UserResolver {
|
|||||||
return new User(dbUser)
|
return new User(dbUser)
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is used by the admin only - should we move it to the admin resolver?
|
|
||||||
@Authorized([RIGHTS.SEND_ACTIVATION_EMAIL])
|
|
||||||
@Mutation(() => Boolean)
|
|
||||||
async sendActivationEmail(@Arg('email') email: string): Promise<boolean> {
|
|
||||||
email = email.trim().toLowerCase()
|
|
||||||
const user = await DbUser.findOneOrFail({ email: email })
|
|
||||||
|
|
||||||
const queryRunner = getConnection().createQueryRunner()
|
|
||||||
await queryRunner.connect()
|
|
||||||
await queryRunner.startTransaction('READ UNCOMMITTED')
|
|
||||||
|
|
||||||
try {
|
|
||||||
const emailOptIn = await createEmailOptIn(user.id, queryRunner)
|
|
||||||
|
|
||||||
const activationLink = CONFIG.EMAIL_LINK_VERIFICATION.replace(
|
|
||||||
/{optin}/g,
|
|
||||||
emailOptIn.verificationCode.toString(),
|
|
||||||
)
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
const emailSent = await sendAccountActivationEmail({
|
|
||||||
link: activationLink,
|
|
||||||
firstName: user.firstName,
|
|
||||||
lastName: user.lastName,
|
|
||||||
email,
|
|
||||||
})
|
|
||||||
|
|
||||||
/* uncomment this, when you need the activation link on the console
|
|
||||||
// In case EMails are disabled log the activation link for the user
|
|
||||||
if (!emailSent) {
|
|
||||||
// eslint-disable-next-line no-console
|
|
||||||
console.log(`Account confirmation link: ${activationLink}`)
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
await queryRunner.commitTransaction()
|
|
||||||
} catch (e) {
|
|
||||||
await queryRunner.rollbackTransaction()
|
|
||||||
throw e
|
|
||||||
} finally {
|
|
||||||
await queryRunner.release()
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
@Authorized([RIGHTS.SEND_RESET_PASSWORD_EMAIL])
|
@Authorized([RIGHTS.SEND_RESET_PASSWORD_EMAIL])
|
||||||
@Query(() => Boolean)
|
@Query(() => Boolean)
|
||||||
async sendResetPasswordEmail(@Arg('email') email: string): Promise<boolean> {
|
async sendResetPasswordEmail(@Arg('email') email: string): Promise<boolean> {
|
||||||
@ -443,29 +393,14 @@ export class UserResolver {
|
|||||||
userId: user.id,
|
userId: user.id,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (optInCode) {
|
optInCode = checkExistingOptInCode(optInCode, user.id)
|
||||||
if (!canResendOptIn(optInCode)) {
|
|
||||||
throw new Error(
|
|
||||||
`email already sent less than $(printTimeDuration(CONFIG.EMAIL_CODE_REQUEST_TIME)} minutes ago`,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
optInCode.updatedAt = new Date()
|
|
||||||
optInCode.resendCount++
|
|
||||||
} else {
|
|
||||||
optInCode = newEmailOptIn(user.id)
|
|
||||||
}
|
|
||||||
// now it is RESET_PASSWORD
|
// now it is RESET_PASSWORD
|
||||||
optInCode.emailOptInTypeId = OptInType.EMAIL_OPT_IN_RESET_PASSWORD
|
optInCode.emailOptInTypeId = OptInType.EMAIL_OPT_IN_RESET_PASSWORD
|
||||||
await LoginEmailOptIn.save(optInCode)
|
await LoginEmailOptIn.save(optInCode)
|
||||||
|
|
||||||
const link = CONFIG.EMAIL_LINK_SETPASSWORD.replace(
|
|
||||||
/{optin}/g,
|
|
||||||
optInCode.verificationCode.toString(),
|
|
||||||
)
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const emailSent = await sendResetPasswordEmail({
|
const emailSent = await sendResetPasswordEmail({
|
||||||
link,
|
link: activationLink(optInCode),
|
||||||
firstName: user.firstName,
|
firstName: user.firstName,
|
||||||
lastName: user.lastName,
|
lastName: user.lastName,
|
||||||
email,
|
email,
|
||||||
@ -547,6 +482,7 @@ export class UserResolver {
|
|||||||
throw new Error('error saving user: ' + error)
|
throw new Error('error saving user: ' + error)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// why do we delete the code?
|
||||||
// Delete Code
|
// Delete Code
|
||||||
await queryRunner.manager.remove(optInCode).catch((error) => {
|
await queryRunner.manager.remove(optInCode).catch((error) => {
|
||||||
throw new Error('error deleting code: ' + error)
|
throw new Error('error deleting code: ' + error)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user