2023-02-22 10:41:01 +08:00
|
|
|
import { Inject, Injectable, ForbiddenException } from '@nestjs/common'
|
|
|
|
import * as bcrypt from 'bcrypt'
|
2023-02-15 20:32:14 +08:00
|
|
|
import { PrismaService } from 'nestjs-prisma'
|
2023-02-22 10:41:01 +08:00
|
|
|
import { JwtService } from '@nestjs/jwt'
|
|
|
|
import { securityConfig, SecurityConfig } from 'src/common/configs'
|
|
|
|
import { CreateUserDto } from 'src/users/dto/create-user.dto'
|
|
|
|
import { EmailSendDto, EmailScene } from 'src/email/dto/email.dto'
|
|
|
|
import { EmailService } from 'src/email/email.service'
|
|
|
|
import { TokenService } from './token.service'
|
2023-02-22 16:09:31 +08:00
|
|
|
import { UpdatePassword } from './dto/update-password.dto'
|
2023-02-22 18:37:13 +08:00
|
|
|
import { DeleteUserDto } from './dto/delete-user.dto'
|
|
|
|
|
2023-02-15 20:32:14 +08:00
|
|
|
@Injectable()
|
|
|
|
export class UsersService {
|
2023-02-22 10:41:01 +08:00
|
|
|
constructor(
|
|
|
|
private jwtService: JwtService,
|
|
|
|
private prismaService: PrismaService,
|
|
|
|
private emailService: EmailService,
|
|
|
|
private tokenService: TokenService,
|
|
|
|
@Inject(securityConfig.KEY)
|
|
|
|
private secureConfig: SecurityConfig,
|
|
|
|
) {}
|
|
|
|
|
|
|
|
async register(userToCreate: CreateUserDto) {
|
|
|
|
await this.verifyEmail(
|
|
|
|
userToCreate.email,
|
|
|
|
userToCreate.token,
|
2023-02-22 16:09:31 +08:00
|
|
|
userToCreate.verifyCode,
|
2023-02-22 10:41:01 +08:00
|
|
|
EmailScene.register,
|
|
|
|
)
|
|
|
|
const hashedPassword = await bcrypt.hash(
|
|
|
|
userToCreate.password,
|
|
|
|
this.secureConfig.bcryptSaltOrRound,
|
|
|
|
)
|
|
|
|
const user = await this.prismaService.user.create({
|
|
|
|
data: {
|
|
|
|
username: userToCreate.username,
|
|
|
|
email: userToCreate.email,
|
|
|
|
password: hashedPassword,
|
|
|
|
},
|
|
|
|
})
|
|
|
|
return this.tokenService.generateTokens({ userId: user.id })
|
|
|
|
}
|
2023-02-22 16:09:31 +08:00
|
|
|
|
2023-02-22 18:37:13 +08:00
|
|
|
async deleteUser(userData: DeleteUserDto) {
|
|
|
|
await this.verifyEmail(
|
|
|
|
userData.email,
|
|
|
|
userData.token,
|
|
|
|
userData.verifyCode,
|
|
|
|
EmailScene.deleteUser,
|
|
|
|
)
|
|
|
|
const user = await this.prismaService.user.findUnique({
|
|
|
|
where: { email: userData.email },
|
|
|
|
})
|
|
|
|
const passwordValid = await bcrypt.compare(user.password, userData.password)
|
|
|
|
if (!passwordValid) {
|
|
|
|
throw new ForbiddenException('Invalid password')
|
|
|
|
}
|
|
|
|
|
|
|
|
return this.prismaService.user.delete({ where: { email: userData.email } })
|
|
|
|
}
|
|
|
|
|
2023-02-22 16:09:31 +08:00
|
|
|
async updatePassword(payload: UpdatePassword) {
|
|
|
|
await this.verifyEmail(
|
|
|
|
payload.email,
|
|
|
|
payload.token,
|
|
|
|
payload.verifyCode,
|
|
|
|
EmailScene.updatePassword,
|
|
|
|
)
|
|
|
|
const hashedPassword = await bcrypt.hash(
|
|
|
|
payload.password,
|
|
|
|
this.secureConfig.bcryptSaltOrRound,
|
|
|
|
)
|
|
|
|
const user = await this.prismaService.user.update({
|
|
|
|
where: { email: payload.email },
|
|
|
|
data: { password: hashedPassword },
|
|
|
|
})
|
|
|
|
return user
|
|
|
|
}
|
|
|
|
|
|
|
|
private async verifyEmail(
|
|
|
|
email: string,
|
|
|
|
token: string,
|
|
|
|
verifyCode: string,
|
|
|
|
scene: EmailScene,
|
|
|
|
) {
|
|
|
|
const payload = this.jwtService.verify<EmailSendDto>(token, {
|
|
|
|
secret: this.emailService.getEmailJwtSecret(verifyCode, scene),
|
|
|
|
})
|
|
|
|
if (payload.email !== email || payload.scene !== scene) {
|
|
|
|
throw new ForbiddenException('请输入正确的邮箱验证码')
|
|
|
|
}
|
|
|
|
}
|
2023-02-15 20:32:14 +08:00
|
|
|
}
|