2023-02-23 17:09:41 +08:00
|
|
|
import { Inject, Injectable, UnauthorizedException } from '@nestjs/common'
|
2023-02-22 10:41:01 +08:00
|
|
|
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'
|
2023-02-23 17:09:41 +08:00
|
|
|
import { securityConfig, type SecurityConfig } from 'src/common/configs'
|
2023-02-22 10:41:01 +08:00
|
|
|
import { CreateUserDto } from 'src/users/dto/create-user.dto'
|
2023-02-23 17:09:41 +08:00
|
|
|
import { EmailScene } from 'src/email/dto/email.dto'
|
2023-02-22 10:41:01 +08:00
|
|
|
import { EmailService } from 'src/email/email.service'
|
2023-02-23 17:09:41 +08:00
|
|
|
import { ResetPassword } from './dto/reset-password.dto'
|
|
|
|
import { Token, TokenPayload } from './dto/token.dto'
|
2023-02-22 18:37:13 +08:00
|
|
|
|
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,
|
2023-02-23 17:09:41 +08:00
|
|
|
@Inject(securityConfig.KEY) private secureConfig: SecurityConfig,
|
2023-02-22 10:41:01 +08:00
|
|
|
) {}
|
|
|
|
|
2023-02-23 17:09:41 +08:00
|
|
|
async registerByEmail(userToCreate: CreateUserDto) {
|
|
|
|
const { email, token, verifyCode, username, password } = userToCreate
|
|
|
|
await this.emailService.verifyEmail({
|
|
|
|
email,
|
|
|
|
token,
|
|
|
|
verifyCode,
|
|
|
|
scene: EmailScene.register,
|
|
|
|
})
|
2023-02-22 10:41:01 +08:00
|
|
|
const hashedPassword = await bcrypt.hash(
|
2023-02-23 17:09:41 +08:00
|
|
|
password,
|
2023-02-22 10:41:01 +08:00
|
|
|
this.secureConfig.bcryptSaltOrRound,
|
|
|
|
)
|
|
|
|
const user = await this.prismaService.user.create({
|
2023-02-23 17:09:41 +08:00
|
|
|
data: { username, email, password: hashedPassword },
|
2023-02-22 10:41:01 +08:00
|
|
|
})
|
2023-02-23 17:09:41 +08:00
|
|
|
return this.generateTokens({ userId: user.id })
|
2023-02-22 10:41:01 +08:00
|
|
|
}
|
2023-02-22 16:09:31 +08:00
|
|
|
|
2023-02-23 17:09:41 +08:00
|
|
|
async loginByEmail(email: string, password: string) {
|
2023-02-23 10:13:50 +08:00
|
|
|
const user = await this.prismaService.user.findUniqueOrThrow({
|
2023-02-23 17:09:41 +08:00
|
|
|
where: { email },
|
2023-02-22 18:37:13 +08:00
|
|
|
})
|
2023-02-23 17:09:41 +08:00
|
|
|
|
|
|
|
const passwordValid = await bcrypt.compare(password, user.password)
|
|
|
|
|
2023-02-22 18:37:13 +08:00
|
|
|
if (!passwordValid) {
|
2023-02-23 17:09:41 +08:00
|
|
|
throw new UnauthorizedException('Invalid password')
|
2023-02-22 18:37:13 +08:00
|
|
|
}
|
|
|
|
|
2023-02-23 17:09:41 +08:00
|
|
|
return this.generateTokens({ userId: user.id })
|
2023-02-22 18:37:13 +08:00
|
|
|
}
|
|
|
|
|
2023-02-23 17:09:41 +08:00
|
|
|
async resetPasswordByEmail(data: ResetPassword, userId: string) {
|
|
|
|
const { email, token, verifyCode, password } = data
|
|
|
|
await this.emailService.verifyEmail({
|
|
|
|
email,
|
|
|
|
token,
|
|
|
|
verifyCode,
|
|
|
|
scene: EmailScene.forgetPassword,
|
2023-02-23 14:23:51 +08:00
|
|
|
})
|
|
|
|
const hashedPassword = await bcrypt.hash(
|
2023-02-23 17:09:41 +08:00
|
|
|
password,
|
2023-02-23 14:23:51 +08:00
|
|
|
this.secureConfig.bcryptSaltOrRound,
|
|
|
|
)
|
2023-02-23 17:09:41 +08:00
|
|
|
const user = await this.prismaService.user.update({
|
2023-02-23 14:23:51 +08:00
|
|
|
where: { id: userId },
|
|
|
|
data: { password: hashedPassword },
|
|
|
|
})
|
2023-02-23 17:09:41 +08:00
|
|
|
return this.generateTokens({ userId: user.id })
|
2023-02-23 14:23:51 +08:00
|
|
|
}
|
|
|
|
|
2023-02-23 17:09:41 +08:00
|
|
|
private generateTokens(payload: TokenPayload): Token {
|
|
|
|
const accessToken = this.jwtService.sign(payload, {
|
|
|
|
secret: this.secureConfig.jwt_access_secret,
|
|
|
|
expiresIn: this.secureConfig.expiresIn,
|
2023-02-22 16:09:31 +08:00
|
|
|
})
|
2023-02-23 17:09:41 +08:00
|
|
|
const refreshToken = this.jwtService.sign(payload, {
|
|
|
|
secret: this.secureConfig.jwt_refresh_secret,
|
|
|
|
expiresIn: this.secureConfig.refreshIn,
|
2023-02-22 16:09:31 +08:00
|
|
|
})
|
2023-02-23 17:09:41 +08:00
|
|
|
|
|
|
|
return { accessToken, refreshToken, ...payload }
|
2023-02-22 16:09:31 +08:00
|
|
|
}
|
2023-02-15 20:32:14 +08:00
|
|
|
}
|