import { ConflictException, Inject, Injectable } from '@nestjs/common' import { securityConfig, SecurityConfig } from 'src/common/configs' import { MailerService } from '@nestjs-modules/mailer' import { JwtService } from '@nestjs/jwt' import { EmailScene } from './dto/email.dto' import { PrismaService } from 'nestjs-prisma' @Injectable() export class EmailService { private subjectMap = { [EmailScene.register]: '注册账号', [EmailScene.updatePassword]: '修改密码', [EmailScene.updateEmail]: '修改邮箱', } constructor( private prismaService: PrismaService, private mailerService: MailerService, private jwtService: JwtService, @Inject(securityConfig.KEY) private secureConfig: SecurityConfig, ) {} async sendEmailToken(email: string, scene: EmailScene) { switch (scene) { case EmailScene.register: const user = await this.prismaService.user.findUnique({ where: { email }, }) if (user) { throw new ConflictException(`邮箱${email}已注册`) } break case EmailScene.updatePassword: await this.prismaService.user.findUniqueOrThrow({ where: { email }, }) break case EmailScene.updateEmail: await this.prismaService.user.findUniqueOrThrow({ where: { email }, }) break } const verifyCode = this.generateVerifyCode() const registerToken = this.jwtService.sign( { email, scene }, { secret: this.getEmailJwtSecret(verifyCode, scene) }, ) await this.mailerService.sendMail({ to: email, subject: `【qiuxu.site】${this.subjectMap[scene]}`, html: `您正在qiuxu.site${this.subjectMap[scene]},验证码为 ${verifyCode},30分钟内有效`, }) return registerToken } getEmailJwtSecret(verifyCode: string, scene: EmailScene) { return this.secureConfig.jwt_access_secret + verifyCode + scene } private generateVerifyCode() { return Math.floor(Math.random() * 899999 + 100000).toString() } }