113 lines
3.0 KiB
TypeScript
113 lines
3.0 KiB
TypeScript
import { Injectable, UnauthorizedException } from '@nestjs/common';
|
|
import { JwtService } from '@nestjs/jwt';
|
|
import * as bcrypt from 'bcryptjs';
|
|
import { DatabaseService } from '../database/database.service';
|
|
import { User, AuthUser } from '../types';
|
|
|
|
@Injectable()
|
|
export class AuthService {
|
|
constructor(
|
|
private dbService: DatabaseService,
|
|
private jwtService: JwtService,
|
|
) {}
|
|
|
|
async validateUser(username: string, password: string) {
|
|
const user = await this.dbService.get<User>('SELECT * FROM users WHERE username = ?', [username]);
|
|
|
|
if (!user) {
|
|
throw new UnauthorizedException('用户名或密码错误');
|
|
}
|
|
|
|
const isValidPassword = await bcrypt.compare(password, user.password);
|
|
|
|
if (!isValidPassword) {
|
|
throw new UnauthorizedException('用户名或密码错误');
|
|
}
|
|
|
|
return user;
|
|
}
|
|
|
|
async login(user: User) {
|
|
const payload = { userId: user.id, username: user.username, role: user.role };
|
|
const token = this.jwtService.sign(payload);
|
|
|
|
return {
|
|
accessToken: token,
|
|
user: {
|
|
id: user.id,
|
|
username: user.username,
|
|
name: user.name,
|
|
email: user.email,
|
|
role: user.role,
|
|
createdAt: user.created_at,
|
|
},
|
|
};
|
|
}
|
|
|
|
async getProfile(userId: number) {
|
|
const user = await this.dbService.get<User>(
|
|
'SELECT id, username, name, email, role, created_at FROM users WHERE id = ?',
|
|
[userId],
|
|
);
|
|
|
|
if (!user) {
|
|
throw new UnauthorizedException('用户不存在');
|
|
}
|
|
|
|
return {
|
|
id: user.id,
|
|
username: user.username,
|
|
name: user.name,
|
|
email: user.email,
|
|
role: user.role,
|
|
createdAt: user.created_at,
|
|
};
|
|
}
|
|
|
|
async changePassword(userId: number, currentPassword: string, newPassword: string) {
|
|
const user = await this.dbService.get<Pick<User, 'password'>>('SELECT password FROM users WHERE id = ?', [
|
|
userId,
|
|
]);
|
|
|
|
if (!user) {
|
|
throw new UnauthorizedException('用户不存在');
|
|
}
|
|
|
|
const isValidPassword = await bcrypt.compare(currentPassword, user.password);
|
|
|
|
if (!isValidPassword) {
|
|
throw new UnauthorizedException('当前密码错误');
|
|
}
|
|
|
|
const hashedPassword = await bcrypt.hash(newPassword, 10);
|
|
|
|
await this.dbService.run('UPDATE users SET password = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?', [
|
|
hashedPassword,
|
|
userId,
|
|
]);
|
|
|
|
return { message: '密码修改成功' };
|
|
}
|
|
|
|
async updateProfile(userId: number, name: string, email: string | null) {
|
|
await this.dbService.run(
|
|
'UPDATE users SET name = ?, email = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?',
|
|
[name, email, userId],
|
|
);
|
|
|
|
const updatedUser = await this.dbService.get<User>(
|
|
'SELECT id, username, name, email, role, created_at FROM users WHERE id = ?',
|
|
[userId],
|
|
);
|
|
|
|
return {
|
|
id: updatedUser!.id,
|
|
username: updatedUser!.username,
|
|
name: updatedUser!.name,
|
|
email: updatedUser!.email,
|
|
role: updatedUser!.role,
|
|
createdAt: updatedUser!.created_at,
|
|
};
|
|
}
|
|
}
|