oa_based/src/modules/auth/auth.service.ts

163 lines
5.0 KiB
TypeScript
Raw Normal View History

2024-02-28 17:02:46 +08:00
import { InjectRedis } from '@liaoliaots/nestjs-redis';
import { Injectable } from '@nestjs/common';
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
import Redis from 'ioredis';
import { isEmpty } from 'lodash';
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
import { BusinessException } from '~/common/exceptions/biz.exception';
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
import { ErrorEnum } from '~/constants/error-code.constant';
import { genAuthPVKey, genAuthPermKey, genAuthTokenKey } from '~/helper/genRedisKey';
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
import { UserService } from '~/modules/user/user.service';
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
import { md5 } from '~/utils';
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
import { LoginLogService } from '../system/log/services/login-log.service';
import { MenuService } from '../system/menu/menu.service';
import { RoleService } from '../system/role/role.service';
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
import { TokenService } from './services/token.service';
2024-02-28 08:32:35 +08:00
@Injectable()
export class AuthService {
constructor(
@InjectRedis() private readonly redis: Redis,
private menuService: MenuService,
private roleService: RoleService,
private userService: UserService,
private loginLogService: LoginLogService,
2024-02-28 17:02:46 +08:00
private tokenService: TokenService
2024-02-28 08:32:35 +08:00
) {}
async validateUser(credential: string, password: string): Promise<any> {
2024-02-28 17:02:46 +08:00
const user = await this.userService.findUserByUserName(credential);
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
if (isEmpty(user)) throw new BusinessException(ErrorEnum.USER_NOT_FOUND);
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
const comparePassword = md5(`${password}${user.psalt}`);
2024-02-28 08:32:35 +08:00
if (user.password !== comparePassword)
2024-02-28 17:02:46 +08:00
throw new BusinessException(ErrorEnum.INVALID_USERNAME_PASSWORD);
2024-02-28 08:32:35 +08:00
if (user) {
2024-02-28 17:02:46 +08:00
const { password, ...result } = user;
return result;
2024-02-28 08:32:35 +08:00
}
2024-02-28 17:02:46 +08:00
return null;
2024-02-28 08:32:35 +08:00
}
/**
* JWT
* null则账号密码有误
*/
2024-02-28 17:02:46 +08:00
async login(username: string, password: string, ip: string, ua: string): Promise<string> {
const user = await this.userService.findUserByUserName(username);
if (isEmpty(user)) throw new BusinessException(ErrorEnum.INVALID_USERNAME_PASSWORD);
const comparePassword = md5(`${password}${user.psalt}`);
2024-02-28 08:32:35 +08:00
if (user.password !== comparePassword)
2024-02-28 17:02:46 +08:00
throw new BusinessException(ErrorEnum.INVALID_USERNAME_PASSWORD);
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
const roleIds = await this.roleService.getRoleIdsByUser(user.id);
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
const roles = await this.roleService.getRoleValues(roleIds);
2024-02-28 08:32:35 +08:00
// 包含access_token和refresh_token
2024-02-28 17:02:46 +08:00
const token = await this.tokenService.generateAccessToken(user.id, roles);
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
await this.redis.set(genAuthTokenKey(user.id), token.accessToken);
2024-02-28 08:32:35 +08:00
// 设置密码版本号 当密码修改时,版本号+1
2024-02-28 17:02:46 +08:00
await this.redis.set(genAuthPVKey(user.id), 1);
2024-02-28 08:32:35 +08:00
// 设置菜单权限
2024-02-28 17:02:46 +08:00
const permissions = await this.menuService.getPermissions(user.id);
await this.setPermissionsCache(user.id, permissions);
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
await this.loginLogService.create(user.id, ip, ua);
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
return token.accessToken;
2024-02-28 08:32:35 +08:00
}
2024-03-01 16:00:42 +08:00
/**
*
* null则账号密码有误
*/
async unlock(uid: number, password: string): Promise<void> {
const user = await this.userService.findUserById(uid);
if (isEmpty(user)) throw new BusinessException(ErrorEnum.INVALID_USERNAME_PASSWORD);
const comparePassword = md5(`${password}${user.psalt}`);
if (user.password !== comparePassword)
throw new BusinessException(ErrorEnum.INVALID_USERNAME_PASSWORD);
}
2024-02-28 08:32:35 +08:00
/**
*
*/
async checkPassword(username: string, password: string) {
2024-02-28 17:02:46 +08:00
const user = await this.userService.findUserByUserName(username);
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
const comparePassword = md5(`${password}${user.psalt}`);
2024-02-28 08:32:35 +08:00
if (user.password !== comparePassword)
2024-02-28 17:02:46 +08:00
throw new BusinessException(ErrorEnum.INVALID_USERNAME_PASSWORD);
2024-02-28 08:32:35 +08:00
}
async loginLog(uid: number, ip: string, ua: string) {
2024-02-28 17:02:46 +08:00
await this.loginLogService.create(uid, ip, ua);
2024-02-28 08:32:35 +08:00
}
async logout(uid: number) {
// 删除token
2024-02-28 17:02:46 +08:00
await this.userService.forbidden(uid);
2024-02-28 08:32:35 +08:00
}
/**
*
*/
async resetPassword(username: string, password: string) {
2024-02-28 17:02:46 +08:00
const user = await this.userService.findUserByUserName(username);
2024-02-28 08:32:35 +08:00
2024-02-28 17:02:46 +08:00
await this.userService.forceUpdatePassword(user.id, password);
2024-02-28 08:32:35 +08:00
}
/**
*
*/
async clearLoginStatus(uid: number): Promise<void> {
2024-02-28 17:02:46 +08:00
await this.userService.forbidden(uid);
2024-02-28 08:32:35 +08:00
}
/**
*
*/
2024-04-10 17:39:17 +08:00
async getMenus(uid: number, isApp: number): Promise<string[]> {
return this.menuService.getMenus(uid,isApp);
2024-02-28 08:32:35 +08:00
}
/**
*
*/
async getPermissions(uid: number): Promise<string[]> {
2024-02-28 17:02:46 +08:00
return this.menuService.getPermissions(uid);
2024-02-28 08:32:35 +08:00
}
async getPermissionsCache(uid: number): Promise<string[]> {
2024-02-28 17:02:46 +08:00
const permissionString = await this.redis.get(genAuthPermKey(uid));
return permissionString ? JSON.parse(permissionString) : [];
2024-02-28 08:32:35 +08:00
}
async setPermissionsCache(uid: number, permissions: string[]): Promise<void> {
2024-02-28 17:02:46 +08:00
await this.redis.set(genAuthPermKey(uid), JSON.stringify(permissions));
2024-02-28 08:32:35 +08:00
}
async getPasswordVersionByUid(uid: number): Promise<string> {
2024-02-28 17:02:46 +08:00
return this.redis.get(genAuthPVKey(uid));
2024-02-28 08:32:35 +08:00
}
async getTokenByUid(uid: number): Promise<string> {
2024-02-28 17:02:46 +08:00
return this.redis.get(genAuthTokenKey(uid));
2024-02-28 08:32:35 +08:00
}
}