mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
first of several calls regarding password reset
This commit is contained in:
parent
6fcce8bf57
commit
728aaa095f
@ -53,6 +53,8 @@ const email = {
|
||||
EMAIL_SMTP_PORT: process.env.EMAIL_SMTP_PORT || '587',
|
||||
EMAIL_LINK_VERIFICATION:
|
||||
process.env.EMAIL_LINK_VERIFICATION || 'http://localhost/vue/checkEmail/$1',
|
||||
EMAIL_LINK_SETPASSWORD:
|
||||
process.env.EMAIL_LINK_SETPASSWORD || 'http://localhost/vue/setPassword/$1',
|
||||
}
|
||||
|
||||
// This is needed by graphql-directive-auth
|
||||
|
||||
@ -1,17 +0,0 @@
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/* eslint-disable @typescript-eslint/explicit-module-boundary-types */
|
||||
import { ObjectType, Field } from 'type-graphql'
|
||||
|
||||
@ObjectType()
|
||||
export class SendPasswordResetEmailResponse {
|
||||
constructor(json: any) {
|
||||
this.state = json.state
|
||||
this.msg = json.msg
|
||||
}
|
||||
|
||||
@Field(() => String)
|
||||
state: string
|
||||
|
||||
@Field(() => String)
|
||||
msg?: string
|
||||
}
|
||||
@ -6,7 +6,6 @@ import { Resolver, Query, Args, Arg, Authorized, Ctx, UseMiddleware, Mutation }
|
||||
import { getConnection, getCustomRepository } from 'typeorm'
|
||||
import CONFIG from '../../config'
|
||||
import { LoginViaVerificationCode } from '../model/LoginViaVerificationCode'
|
||||
import { SendPasswordResetEmailResponse } from '../model/SendPasswordResetEmailResponse'
|
||||
import { User } from '../model/User'
|
||||
import { User as DbUser } from '@entity/User'
|
||||
import encode from '../../jwt/encode'
|
||||
@ -30,6 +29,7 @@ import { LoginUserBackup } from '@entity/LoginUserBackup'
|
||||
import { LoginEmailOptIn } from '@entity/LoginEmailOptIn'
|
||||
import { sendEMail } from '../../util/sendEMail'
|
||||
import { LoginElopageBuysRepository } from '../../typeorm/repository/LoginElopageBuys'
|
||||
import { randomBytes } from 'crypto'
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const sodium = require('sodium-native')
|
||||
@ -201,8 +201,6 @@ export class UserResolver {
|
||||
@Ctx() context: any,
|
||||
): Promise<User> {
|
||||
email = email.trim().toLowerCase()
|
||||
// const result = await apiPost(CONFIG.LOGIN_API_URL + 'unsecureLogin', { email, password })
|
||||
// UnsecureLogin
|
||||
const loginUserRepository = getCustomRepository(LoginUserRepository)
|
||||
const loginUser = await loginUserRepository.findByEmail(email).catch(() => {
|
||||
throw new Error('No user with this credentials')
|
||||
@ -440,20 +438,60 @@ export class UserResolver {
|
||||
return 'success'
|
||||
}
|
||||
|
||||
@Query(() => SendPasswordResetEmailResponse)
|
||||
async sendResetPasswordEmail(
|
||||
@Arg('email') email: string,
|
||||
): Promise<SendPasswordResetEmailResponse> {
|
||||
const payload = {
|
||||
email,
|
||||
email_text: 7,
|
||||
email_verification_code_type: 'resetPassword',
|
||||
@Query(() => Boolean)
|
||||
async sendResetPasswordEmail(@Arg('email') email: string): Promise<boolean> {
|
||||
let emailAlreadySend = false
|
||||
const EMAIL_OPT_IN_RESET_PASSWORD = 2
|
||||
|
||||
const loginUser = await LoginUser.findOneOrFail({ email })
|
||||
|
||||
let optInCode = await LoginEmailOptIn.findOne({
|
||||
userId: loginUser.id,
|
||||
emailOptInTypeId: EMAIL_OPT_IN_RESET_PASSWORD,
|
||||
})
|
||||
if (optInCode) {
|
||||
emailAlreadySend = true
|
||||
} else {
|
||||
optInCode = new LoginEmailOptIn()
|
||||
optInCode.verificationCode = randomBytes(16).readBigInt64LE()
|
||||
optInCode.userId = loginUser.id
|
||||
optInCode.emailOptInTypeId = EMAIL_OPT_IN_RESET_PASSWORD
|
||||
await optInCode.save()
|
||||
}
|
||||
const response = await apiPost(CONFIG.LOGIN_API_URL + 'sendEmail', payload)
|
||||
if (!response.success) {
|
||||
throw new Error(response.data)
|
||||
|
||||
const link = CONFIG.EMAIL_LINK_SETPASSWORD.replace(
|
||||
/\$1/g,
|
||||
optInCode.verificationCode.toString(),
|
||||
)
|
||||
|
||||
if (emailAlreadySend) {
|
||||
const timeElapsed = Date.now() - new Date(optInCode.updatedAt).getTime()
|
||||
if (timeElapsed < 10 * 60 * 1000) {
|
||||
throw new Error('email already sent less than a 10 minutes before')
|
||||
}
|
||||
}
|
||||
return new SendPasswordResetEmailResponse(response.data)
|
||||
|
||||
const emailSent = await sendEMail({
|
||||
from: `Gradido (nicht antworten) <${CONFIG.EMAIL_SENDER}>`,
|
||||
to: `${loginUser.firstName} ${loginUser.lastName} <${email}>`,
|
||||
subject: 'Gradido: Reset Password',
|
||||
text: `Hallo ${loginUser.firstName} ${loginUser.lastName},
|
||||
|
||||
Du oder jemand anderes hat für dieses Konto ein Zurücksetzen des Passworts angefordert.
|
||||
Wenn du es warst, klicke bitte auf den Link: ${link}
|
||||
oder kopiere den obigen Link in Dein Browserfenster.
|
||||
|
||||
Mit freundlichen Grüßen,
|
||||
dein Gradido-Team`,
|
||||
})
|
||||
|
||||
// In case EMails are disabled log the activation link for the user
|
||||
if (!emailSent) {
|
||||
// eslint-disable-next-line no-console
|
||||
console.log(`Reset password link: ${link}`)
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@Mutation(() => String)
|
||||
|
||||
@ -67,9 +67,7 @@ export const transactionsQuery = gql`
|
||||
|
||||
export const sendResetPasswordEmail = gql`
|
||||
query($email: String!) {
|
||||
sendResetPasswordEmail(email: $email) {
|
||||
state
|
||||
}
|
||||
sendResetPasswordEmail(email: $email)
|
||||
}
|
||||
`
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user