import { Injectable, UnauthorizedException, BadRequestException, OnModuleInit, } from '@nestjs/common'; import { JwtService } from '@nestjs/jwt'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import * as bcrypt from 'bcrypt'; import { User, UserRole } from '../entities/user.entity'; import { RegisterDto } from './dto/register.dto'; import { LoginDto } from './dto/login.dto'; @Injectable() export class AuthService implements OnModuleInit { constructor( @InjectRepository(User) private userRepository: Repository, private jwtService: JwtService, ) {} async onModuleInit() { const adminEmail = 'admin@example.com'; const adminExists = await this.userRepository.findOne({ where: { email: adminEmail }, }); if (!adminExists) { const salt = await bcrypt.genSalt(); const passwordHash = await bcrypt.hash('123456', salt); const adminUser = this.userRepository.create({ email: adminEmail, passwordHash, nickname: 'Admin', role: UserRole.ADMIN, }); await this.userRepository.save(adminUser); console.log(`Admin user initialized: ${adminEmail}`); } else { // Ensure the role is ADMIN and update password if needed if (adminExists.role !== UserRole.ADMIN) { adminExists.role = UserRole.ADMIN; await this.userRepository.save(adminExists); } } } async register(registerDto: RegisterDto) { const { email, password, emailCode, nickname } = registerDto; // In a real app, verify emailCode here if (emailCode !== '123456') { throw new BadRequestException('Invalid Email code'); } const existingUser = await this.userRepository.findOne({ where: { email }, }); if (existingUser) { throw new BadRequestException('User already exists'); } const salt = await bcrypt.genSalt(); const passwordHash = await bcrypt.hash(password, salt); const user = this.userRepository.create({ email, passwordHash, nickname: nickname || `User_${email.split('@')[0].slice(0, 6)}`, role: UserRole.USER, }); await this.userRepository.save(user); return this.login({ email, password }); } async login(loginDto: LoginDto) { const { email, password } = loginDto; const user = await this.userRepository.findOne({ where: { email } }); if (!user) { throw new UnauthorizedException('Invalid credentials'); } const isMatch = await bcrypt.compare(password, user.passwordHash); if (!isMatch) { throw new UnauthorizedException('Invalid credentials'); } const payload = { sub: user.id, email: user.email, role: user.role }; return { userId: user.id, token: this.jwtService.sign(payload), role: user.role, nickname: user.nickname, isVip: user.isVip, }; } async getProfile(userId: number) { const user = await this.userRepository.findOne({ where: { id: userId }, select: ['id', 'email', 'nickname', 'avatar', 'role', 'isVip', 'createdAt'], }); if (!user) { throw new UnauthorizedException('User not found'); } return user; } }