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

163 lines
5.0 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { InjectRedis } from '@liaoliaots/nestjs-redis';
import { Injectable } from '@nestjs/common';
import Redis from 'ioredis';
import { isEmpty } from 'lodash';
import { BusinessException } from '~/common/exceptions/biz.exception';
import { ErrorEnum } from '~/constants/error-code.constant';
import { genAuthPVKey, genAuthPermKey, genAuthTokenKey } from '~/helper/genRedisKey';
import { UserService } from '~/modules/user/user.service';
import { md5 } from '~/utils';
import { LoginLogService } from '../system/log/services/login-log.service';
import { MenuService } from '../system/menu/menu.service';
import { RoleService } from '../system/role/role.service';
import { TokenService } from './services/token.service';
@Injectable()
export class AuthService {
constructor(
@InjectRedis() private readonly redis: Redis,
private menuService: MenuService,
private roleService: RoleService,
private userService: UserService,
private loginLogService: LoginLogService,
private tokenService: TokenService
) {}
async validateUser(credential: string, password: string): Promise<any> {
const user = await this.userService.findUserByUserName(credential);
if (isEmpty(user)) throw new BusinessException(ErrorEnum.USER_NOT_FOUND);
const comparePassword = md5(`${password}${user.psalt}`);
if (user.password !== comparePassword)
throw new BusinessException(ErrorEnum.INVALID_USERNAME_PASSWORD);
if (user) {
const { password, ...result } = user;
return result;
}
return null;
}
/**
* 获取登录JWT
* 返回null则账号密码有误不存在该用户
*/
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}`);
if (user.password !== comparePassword)
throw new BusinessException(ErrorEnum.INVALID_USERNAME_PASSWORD);
const roleIds = await this.roleService.getRoleIdsByUser(user.id);
const roles = await this.roleService.getRoleValues(roleIds);
// 包含access_token和refresh_token
const token = await this.tokenService.generateAccessToken(user.id, roles);
await this.redis.set(genAuthTokenKey(user.id), token.accessToken);
// 设置密码版本号 当密码修改时,版本号+1
await this.redis.set(genAuthPVKey(user.id), 1);
// 设置菜单权限
const permissions = await this.menuService.getPermissions(user.id);
await this.setPermissionsCache(user.id, permissions);
await this.loginLogService.create(user.id, ip, ua);
return token.accessToken;
}
/**
* 解锁屏幕
* 返回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);
}
/**
* 效验账号密码
*/
async checkPassword(username: string, password: string) {
const user = await this.userService.findUserByUserName(username);
const comparePassword = md5(`${password}${user.psalt}`);
if (user.password !== comparePassword)
throw new BusinessException(ErrorEnum.INVALID_USERNAME_PASSWORD);
}
async loginLog(uid: number, ip: string, ua: string) {
await this.loginLogService.create(uid, ip, ua);
}
async logout(uid: number) {
// 删除token
await this.userService.forbidden(uid);
}
/**
* 重置密码
*/
async resetPassword(username: string, password: string) {
const user = await this.userService.findUserByUserName(username);
await this.userService.forceUpdatePassword(user.id, password);
}
/**
* 清除登录状态信息
*/
async clearLoginStatus(uid: number): Promise<void> {
await this.userService.forbidden(uid);
}
/**
* 获取菜单列表
*/
async getMenus(uid: number, isApp: number): Promise<string[]> {
return this.menuService.getMenus(uid,isApp);
}
/**
* 获取权限列表
*/
async getPermissions(uid: number): Promise<string[]> {
return this.menuService.getPermissions(uid);
}
async getPermissionsCache(uid: number): Promise<string[]> {
const permissionString = await this.redis.get(genAuthPermKey(uid));
return permissionString ? JSON.parse(permissionString) : [];
}
async setPermissionsCache(uid: number, permissions: string[]): Promise<void> {
await this.redis.set(genAuthPermKey(uid), JSON.stringify(permissions));
}
async getPasswordVersionByUid(uid: number): Promise<string> {
return this.redis.get(genAuthPVKey(uid));
}
async getTokenByUid(uid: number): Promise<string> {
return this.redis.get(genAuthTokenKey(uid));
}
}