|
|
@ -1,7 +1,7 @@ |
|
|
|
import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; |
|
|
|
import { HttpException, HttpStatus, Injectable } from '@nestjs/common'; |
|
|
|
import { CreateAuthUserDto } from './dto/create-auth-user.dto'; |
|
|
|
import { CreateAuthUserDto } from './dto/create-auth-user.dto'; |
|
|
|
import { UpdateAuthUserDto } from './dto/update-auth-user.dto'; |
|
|
|
import { UpdateAuthUserDto } from './dto/update-auth-user.dto'; |
|
|
|
import { PacInfoType } from '@utils/myType'; |
|
|
|
import { GuardInfo } from '@utils/myType'; |
|
|
|
import { LoggerService } from '@service/logger/logger.service'; |
|
|
|
import { LoggerService } from '@service/logger/logger.service'; |
|
|
|
import { MysqlService } from '@common/service/mysql/mysql.service'; |
|
|
|
import { MysqlService } from '@common/service/mysql/mysql.service'; |
|
|
|
import { RedisService } from '@common/service/redis/redis.service'; |
|
|
|
import { RedisService } from '@common/service/redis/redis.service'; |
|
|
@ -31,6 +31,7 @@ import { UpdateLinkDto } from '@app/auth-user/dto/updateLink.dto'; |
|
|
|
import { UsernameSignInDto } from '@app/auth-user/dto/signin.dto'; |
|
|
|
import { UsernameSignInDto } from '@app/auth-user/dto/signin.dto'; |
|
|
|
import { JwtService } from '@common/service/jwt/jwt.service'; |
|
|
|
import { JwtService } from '@common/service/jwt/jwt.service'; |
|
|
|
import MD5 from '@utils/MD5'; |
|
|
|
import MD5 from '@utils/MD5'; |
|
|
|
|
|
|
|
import { KEY } from '@utils/key'; |
|
|
|
|
|
|
|
|
|
|
|
@Injectable() |
|
|
|
@Injectable() |
|
|
|
export class AuthUserService { |
|
|
|
export class AuthUserService { |
|
|
@ -79,7 +80,7 @@ export class AuthUserService { |
|
|
|
* DESC: 创建账户 |
|
|
|
* DESC: 创建账户 |
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
* */ |
|
|
|
* */ |
|
|
|
public async create(createAuthUserDto: CreateAuthUserDto, pacInfo: PacInfoType) { |
|
|
|
public async create(createAuthUserDto: CreateAuthUserDto, guardInfo: GuardInfo) { |
|
|
|
// ! 加目标锁,同级,而不是全局
|
|
|
|
// ! 加目标锁,同级,而不是全局
|
|
|
|
const lock = await this.redisService.distributedLock('USER' + createAuthUserDto.username, createAuthUserDto.username); |
|
|
|
const lock = await this.redisService.distributedLock('USER' + createAuthUserDto.username, createAuthUserDto.username); |
|
|
|
|
|
|
|
|
|
|
@ -94,7 +95,7 @@ export class AuthUserService { |
|
|
|
if (result.length > 0) throw new HttpException('用户名重复!', HttpStatus.CONFLICT); |
|
|
|
if (result.length > 0) throw new HttpException('用户名重复!', HttpStatus.CONFLICT); |
|
|
|
|
|
|
|
|
|
|
|
// ! 添加账户数据
|
|
|
|
// ! 添加账户数据
|
|
|
|
const newPacCoreDict = await this.addUser(createAuthUserDto, pacInfo); |
|
|
|
const newPacCoreDict = await this.addUser(createAuthUserDto, guardInfo); |
|
|
|
|
|
|
|
|
|
|
|
// ! 解锁
|
|
|
|
// ! 解锁
|
|
|
|
lock(); |
|
|
|
lock(); |
|
|
@ -103,17 +104,17 @@ export class AuthUserService { |
|
|
|
|
|
|
|
|
|
|
|
// ! 关联角色
|
|
|
|
// ! 关联角色
|
|
|
|
if (createAuthUserDto.roleList && createAuthUserDto.roleList.length > 0) { |
|
|
|
if (createAuthUserDto.roleList && createAuthUserDto.roleList.length > 0) { |
|
|
|
insertList.push(this.updateUserRole(newPacCoreDict.userId as any, createAuthUserDto.roleList, pacInfo)); |
|
|
|
insertList.push(this.updateUserRole(newPacCoreDict.userId as any, createAuthUserDto.roleList, guardInfo)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ! 关联部门
|
|
|
|
// ! 关联部门
|
|
|
|
if (createAuthUserDto.deptList && createAuthUserDto.deptList.length > 0) { |
|
|
|
if (createAuthUserDto.deptList && createAuthUserDto.deptList.length > 0) { |
|
|
|
insertList.push(this.updateUserDept(newPacCoreDict.userId as any, createAuthUserDto.deptList, pacInfo)); |
|
|
|
insertList.push(this.updateUserDept(newPacCoreDict.userId as any, createAuthUserDto.deptList, guardInfo)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ! 关联岗位
|
|
|
|
// ! 关联岗位
|
|
|
|
if (createAuthUserDto.postList && createAuthUserDto.postList.length > 0) { |
|
|
|
if (createAuthUserDto.postList && createAuthUserDto.postList.length > 0) { |
|
|
|
insertList.push(this.updateUserPost(newPacCoreDict.userId as any, createAuthUserDto.postList, pacInfo)); |
|
|
|
insertList.push(this.updateUserPost(newPacCoreDict.userId as any, createAuthUserDto.postList, guardInfo)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ! 执行关联
|
|
|
|
// ! 执行关联
|
|
|
@ -165,8 +166,8 @@ export class AuthUserService { |
|
|
|
* DESC: 修改账户信息 |
|
|
|
* DESC: 修改账户信息 |
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
* */ |
|
|
|
* */ |
|
|
|
public update(id: string, updateAuthUserDto: UpdateAuthUserDto, pacInfo: PacInfoType) { |
|
|
|
public update(id: string, updateAuthUserDto: UpdateAuthUserDto, guardInfo: GuardInfo) { |
|
|
|
return this.updateUser(id, updateAuthUserDto, pacInfo); |
|
|
|
return this.updateUser(id, updateAuthUserDto, guardInfo); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** Service |
|
|
|
/** Service |
|
|
@ -174,8 +175,8 @@ export class AuthUserService { |
|
|
|
* DESC: 移除账户 |
|
|
|
* DESC: 移除账户 |
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
* */ |
|
|
|
* */ |
|
|
|
public remove(id: string, pacInfo: PacInfoType) { |
|
|
|
public remove(id: string, guardInfo: GuardInfo) { |
|
|
|
return this.deleteUser(id, pacInfo.userId as any); |
|
|
|
return this.deleteUser(id, guardInfo.userId as any); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/** Service |
|
|
|
/** Service |
|
|
@ -210,10 +211,10 @@ export class AuthUserService { |
|
|
|
* DESC: 修改目标账户角色关联 |
|
|
|
* DESC: 修改目标账户角色关联 |
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
* */ |
|
|
|
* */ |
|
|
|
public async updateLinkRole(id: string, updateLinkDto: UpdateLinkDto, pacInfo: PacInfoType) { |
|
|
|
public async updateLinkRole(id: string, updateLinkDto: UpdateLinkDto, guardInfo: GuardInfo) { |
|
|
|
await this.checkUserExist(id); |
|
|
|
await this.checkUserExist(id); |
|
|
|
if (updateLinkDto) { |
|
|
|
if (updateLinkDto) { |
|
|
|
return this.updateUserRole(id, updateLinkDto.list, pacInfo); |
|
|
|
return this.updateUserRole(id, updateLinkDto.list, guardInfo); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -224,10 +225,10 @@ export class AuthUserService { |
|
|
|
* DESC: 修改目标账户部门关联 |
|
|
|
* DESC: 修改目标账户部门关联 |
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
* */ |
|
|
|
* */ |
|
|
|
public async updateLinkDept(id: string, updateLinkDto: UpdateLinkDto, pacInfo: PacInfoType) { |
|
|
|
public async updateLinkDept(id: string, updateLinkDto: UpdateLinkDto, guardInfo: GuardInfo) { |
|
|
|
await this.checkUserExist(id); |
|
|
|
await this.checkUserExist(id); |
|
|
|
if (updateLinkDto) { |
|
|
|
if (updateLinkDto) { |
|
|
|
return this.updateUserDept(id, updateLinkDto.list, pacInfo); |
|
|
|
return this.updateUserDept(id, updateLinkDto.list, guardInfo); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -238,10 +239,10 @@ export class AuthUserService { |
|
|
|
* DESC: 修改目标账户岗位关联 |
|
|
|
* DESC: 修改目标账户岗位关联 |
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
* */ |
|
|
|
* */ |
|
|
|
public async updateLinkPost(id: string, updateLinkDto: UpdateLinkDto, pacInfo: PacInfoType) { |
|
|
|
public async updateLinkPost(id: string, updateLinkDto: UpdateLinkDto, guardInfo: GuardInfo) { |
|
|
|
await this.checkUserExist(id); |
|
|
|
await this.checkUserExist(id); |
|
|
|
if (updateLinkDto) { |
|
|
|
if (updateLinkDto) { |
|
|
|
return this.updateUserPost(id, updateLinkDto.list, pacInfo); |
|
|
|
return this.updateUserPost(id, updateLinkDto.list, guardInfo); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
@ -249,14 +250,27 @@ export class AuthUserService { |
|
|
|
|
|
|
|
|
|
|
|
/** Service |
|
|
|
/** Service |
|
|
|
* NAME: updateLinkPost |
|
|
|
* NAME: updateLinkPost |
|
|
|
* DESC: 修改目标账户岗位关联 |
|
|
|
* DESC: 登录 |
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
* */ |
|
|
|
* */ |
|
|
|
public async signin(usernameSignInDto: UsernameSignInDto) { |
|
|
|
public async signin(usernameSignInDto: UsernameSignInDto) { |
|
|
|
// 登陆检测
|
|
|
|
// 登录检测
|
|
|
|
return await this.signinDetection(usernameSignInDto); |
|
|
|
return await this.signinDetection(usernameSignInDto); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** Service |
|
|
|
|
|
|
|
* NAME: refreshToken |
|
|
|
|
|
|
|
* DESC: 刷新Token |
|
|
|
|
|
|
|
* DATE: 2024-06-29 13:13:55 - |
|
|
|
|
|
|
|
* */ |
|
|
|
|
|
|
|
public async refreshToken(guardInfo: GuardInfo) { |
|
|
|
|
|
|
|
const token = this.jwt.token({ type: 'token', username: guardInfo.username, userId: guardInfo.userId, timestamp: new Date().getTime() }); |
|
|
|
|
|
|
|
await this.redisService.redis.set(KEY.REDIS_TOKEN + guardInfo.userId + '-' + MD5(token), 0, { |
|
|
|
|
|
|
|
EX: this.config.get<number>('system.signin.tokenTime'), |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
return { token }; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// DB 同级查重
|
|
|
|
// DB 同级查重
|
|
|
|
private checkRepeatForUsername(username: string) { |
|
|
|
private checkRepeatForUsername(username: string) { |
|
|
|
return this.mysqlService.db |
|
|
|
return this.mysqlService.db |
|
|
@ -278,7 +292,7 @@ export class AuthUserService { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// DB 添加账户
|
|
|
|
// DB 添加账户
|
|
|
|
private async addUser(createAuthUserDto: CreateAuthUserDto, pacInfo: PacInfoType) { |
|
|
|
private async addUser(createAuthUserDto: CreateAuthUserDto, guardInfo: GuardInfo) { |
|
|
|
// ! 生成雪花id,用于账户id
|
|
|
|
// ! 生成雪花id,用于账户id
|
|
|
|
const id = await this.snowflake.generate(); |
|
|
|
const id = await this.snowflake.generate(); |
|
|
|
|
|
|
|
|
|
|
@ -309,7 +323,7 @@ export class AuthUserService { |
|
|
|
avatar: createAuthUserDto.avatar, |
|
|
|
avatar: createAuthUserDto.avatar, |
|
|
|
userPhone: createAuthUserDto.userPhone, |
|
|
|
userPhone: createAuthUserDto.userPhone, |
|
|
|
userDesc: createAuthUserDto.userDesc, |
|
|
|
userDesc: createAuthUserDto.userDesc, |
|
|
|
createby: pacInfo.userId as any, |
|
|
|
createby: guardInfo.userId as any, |
|
|
|
createtime: sql`now()` as any, |
|
|
|
createtime: sql`now()` as any, |
|
|
|
}; |
|
|
|
}; |
|
|
|
return { |
|
|
|
return { |
|
|
@ -324,7 +338,7 @@ export class AuthUserService { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// COMMON 向目标表插入列
|
|
|
|
// COMMON 向目标表插入列
|
|
|
|
private async insertKeyValueForUserLink(table, list, key, userId, pacInfo: PacInfoType) { |
|
|
|
private async insertKeyValueForUserLink(table, list, key, userId, guardInfo: GuardInfo) { |
|
|
|
// ! 清空曾经的关联
|
|
|
|
// ! 清空曾经的关联
|
|
|
|
await this.mysqlService.db.delete(table).where(eq(table.userId as any, userId)); |
|
|
|
await this.mysqlService.db.delete(table).where(eq(table.userId as any, userId)); |
|
|
|
|
|
|
|
|
|
|
@ -336,25 +350,25 @@ export class AuthUserService { |
|
|
|
arr.map((i) => ({ |
|
|
|
arr.map((i) => ({ |
|
|
|
userId: userId, |
|
|
|
userId: userId, |
|
|
|
[key]: i, |
|
|
|
[key]: i, |
|
|
|
createby: pacInfo.userId as any, |
|
|
|
createby: guardInfo.userId as any, |
|
|
|
createtime: sql`now()` as any, |
|
|
|
createtime: sql`now()` as any, |
|
|
|
})), |
|
|
|
})), |
|
|
|
); |
|
|
|
); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// DB 修改用户角色
|
|
|
|
// DB 修改用户角色
|
|
|
|
private async updateUserRole(userId: string, roleIdList: string[], pacInfo: PacInfoType) { |
|
|
|
private async updateUserRole(userId: string, roleIdList: string[], guardInfo: GuardInfo) { |
|
|
|
return await this.insertKeyValueForUserLink(pacAuthLinkUserRole, roleIdList, 'roleId', userId, pacInfo); |
|
|
|
return await this.insertKeyValueForUserLink(pacAuthLinkUserRole, roleIdList, 'roleId', userId, guardInfo); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// DB 修改账户部门
|
|
|
|
// DB 修改账户部门
|
|
|
|
private async updateUserDept(userId: string, deptIdList: string[], pacInfo: PacInfoType) { |
|
|
|
private async updateUserDept(userId: string, deptIdList: string[], guardInfo: GuardInfo) { |
|
|
|
return await this.insertKeyValueForUserLink(pacAuthLinkUserDept, deptIdList, 'deptId', userId, pacInfo); |
|
|
|
return await this.insertKeyValueForUserLink(pacAuthLinkUserDept, deptIdList, 'deptId', userId, guardInfo); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// DB修改账户岗位
|
|
|
|
// DB修改账户岗位
|
|
|
|
private async updateUserPost(userId: string, postIdList: string[], pacInfo: PacInfoType) { |
|
|
|
private async updateUserPost(userId: string, postIdList: string[], guardInfo: GuardInfo) { |
|
|
|
return await this.insertKeyValueForUserLink(pacAuthLinkUserPost, postIdList, 'postId', userId, pacInfo); |
|
|
|
return await this.insertKeyValueForUserLink(pacAuthLinkUserPost, postIdList, 'postId', userId, guardInfo); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 查询构建器
|
|
|
|
// 查询构建器
|
|
|
@ -561,7 +575,7 @@ export class AuthUserService { |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// DB 更新账户
|
|
|
|
// DB 更新账户
|
|
|
|
private async updateUser(id: string, updateAuthUserDto: UpdateAuthUserDto, pacInfo: PacInfoType) { |
|
|
|
private async updateUser(id: string, updateAuthUserDto: UpdateAuthUserDto, guardInfo: GuardInfo) { |
|
|
|
const user = await this.mysqlService.db |
|
|
|
const user = await this.mysqlService.db |
|
|
|
.select({ id: pacAuthUser.userId, pid: pacAuthUser.pid }) |
|
|
|
.select({ id: pacAuthUser.userId, pid: pacAuthUser.pid }) |
|
|
|
.from(pacAuthUser) |
|
|
|
.from(pacAuthUser) |
|
|
@ -571,13 +585,13 @@ export class AuthUserService { |
|
|
|
// 用户名不修改不需要查重
|
|
|
|
// 用户名不修改不需要查重
|
|
|
|
|
|
|
|
|
|
|
|
if (updateAuthUserDto.roleList) { |
|
|
|
if (updateAuthUserDto.roleList) { |
|
|
|
await this.updateUserRole(id, updateAuthUserDto.roleList, pacInfo); |
|
|
|
await this.updateUserRole(id, updateAuthUserDto.roleList, guardInfo); |
|
|
|
} |
|
|
|
} |
|
|
|
if (updateAuthUserDto.deptList) { |
|
|
|
if (updateAuthUserDto.deptList) { |
|
|
|
await this.updateUserDept(id, updateAuthUserDto.deptList, pacInfo); |
|
|
|
await this.updateUserDept(id, updateAuthUserDto.deptList, guardInfo); |
|
|
|
} |
|
|
|
} |
|
|
|
if (updateAuthUserDto.postList) { |
|
|
|
if (updateAuthUserDto.postList) { |
|
|
|
await this.updateUserPost(id, updateAuthUserDto.postList, pacInfo); |
|
|
|
await this.updateUserPost(id, updateAuthUserDto.postList, guardInfo); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
return await this.mysqlService.db |
|
|
|
return await this.mysqlService.db |
|
|
@ -590,7 +604,7 @@ export class AuthUserService { |
|
|
|
userPhone: updateAuthUserDto.userPhone, |
|
|
|
userPhone: updateAuthUserDto.userPhone, |
|
|
|
userDesc: updateAuthUserDto.userDesc, |
|
|
|
userDesc: updateAuthUserDto.userDesc, |
|
|
|
status: updateAuthUserDto.status, |
|
|
|
status: updateAuthUserDto.status, |
|
|
|
updateby: pacInfo.userId, |
|
|
|
updateby: guardInfo.userId, |
|
|
|
updatetime: sql`now()`, |
|
|
|
updatetime: sql`now()`, |
|
|
|
}) |
|
|
|
}) |
|
|
|
.where(eq(pacAuthUser.userId, id)); |
|
|
|
.where(eq(pacAuthUser.userId, id)); |
|
|
@ -634,7 +648,7 @@ export class AuthUserService { |
|
|
|
return user[0]; |
|
|
|
return user[0]; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// DB 登陆检测
|
|
|
|
// DB 登录检测
|
|
|
|
private async signinDetection(usernameSignInDto: UsernameSignInDto) { |
|
|
|
private async signinDetection(usernameSignInDto: UsernameSignInDto) { |
|
|
|
const user = await this.mysqlService.db |
|
|
|
const user = await this.mysqlService.db |
|
|
|
.select({ userId: pacAuthUser.userId, pid: pacAuthUser.pid, password: pacAuthUser.password }) |
|
|
|
.select({ userId: pacAuthUser.userId, pid: pacAuthUser.pid, password: pacAuthUser.password }) |
|
|
@ -642,50 +656,79 @@ export class AuthUserService { |
|
|
|
.where(and(isNull(pacAuthUser.deleteby), eq(pacAuthUser.username, usernameSignInDto.username))); |
|
|
|
.where(and(isNull(pacAuthUser.deleteby), eq(pacAuthUser.username, usernameSignInDto.username))); |
|
|
|
if (user.length == 0) throw new HttpException('该用户不存在!', HttpStatus.BAD_REQUEST); |
|
|
|
if (user.length == 0) throw new HttpException('该用户不存在!', HttpStatus.BAD_REQUEST); |
|
|
|
|
|
|
|
|
|
|
|
// ! 判断是否超过最大登录次数
|
|
|
|
// ! 当前账户的userID
|
|
|
|
const number = await this.redisService.get('SIGNIN_NUM' + user[0].userId); |
|
|
|
const userId = user[0].userId; |
|
|
|
let maxNumberFieldsigninForRedis = (await this.redisService.get('CONFIG_MAX_NUMBER_FIELD_SIGNIN')) as any; |
|
|
|
|
|
|
|
if (!maxNumberFieldsigninForRedis) { |
|
|
|
// ! 当前账户的密码
|
|
|
|
maxNumberFieldsigninForRedis = this.config.get<number>('system.signin.maxNumberFieldsignin'); |
|
|
|
const password = user[0].password; |
|
|
|
} |
|
|
|
|
|
|
|
if (Number(number) >= maxNumberFieldsigninForRedis) { |
|
|
|
// ? 判断是否超过最大错误登录次数
|
|
|
|
|
|
|
|
// ! 获取当前用户已经登录失败的次数
|
|
|
|
|
|
|
|
const number = await this.redisService.get(KEY.REDIS_FIELD_SIGNIN_NUM + userId); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ! 从Redis获取系统允许的最大错误次数
|
|
|
|
|
|
|
|
let maxField = (await this.redisService.get(KEY.REDIS_MAX_FIELD_SIGNIN_NUM)) as any; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ? 判断Redis中是否有存储 || 如果不存在,从配置文件取
|
|
|
|
|
|
|
|
maxField = maxField ? maxField : this.config.get<number>('system.signin.maxNumberFieldsignin'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ? 如果当前账户已经错误登录多次,抛出错误
|
|
|
|
|
|
|
|
if (Number(number) >= maxField) { |
|
|
|
throw new HttpException(`登录错误次数过多:${number}次!`, HttpStatus.BAD_REQUEST); |
|
|
|
throw new HttpException(`登录错误次数过多:${number}次!`, HttpStatus.BAD_REQUEST); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ! 验证密码
|
|
|
|
// ! 验证密码
|
|
|
|
const pass = cryptoPassword(usernameSignInDto.password, this.config.get<number>('system.passwordSalt')); |
|
|
|
// ! 加密登录时的密码
|
|
|
|
if (pass != user[0].password) { |
|
|
|
const nowPassword = cryptoPassword(usernameSignInDto.password, this.config.get<number>('system.passwordSalt')); |
|
|
|
let maxTimeFieldsignin = (await this.redisService.get('CONFIG_MAX_TIME_FIELD_SIGNIN')) as any; |
|
|
|
|
|
|
|
if (!maxTimeFieldsignin) { |
|
|
|
// ! 如果登录密码和设置的密码不匹配
|
|
|
|
maxTimeFieldsignin = this.config.get<number>('system.signin.maxTimeFieldsignin'); |
|
|
|
if (nowPassword != password) { |
|
|
|
} |
|
|
|
// ! 从Redis获取冷却时间,(超过最大登陆错误次数后的等待时间)
|
|
|
|
await this.redisService.redis.SET('SIGNIN_NUM' + user[0].userId, Number(number) ? Number(number) + 1 : 1, { |
|
|
|
let waitTime = (await this.redisService.get(KEY.REDIS_WAITING_SIGNIN_TIME)) as any; |
|
|
|
PX: maxTimeFieldsignin, |
|
|
|
|
|
|
|
|
|
|
|
// ? 如果Redis中没有,从环境变量取
|
|
|
|
|
|
|
|
waitTime = waitTime ? waitTime : this.config.get<number>('system.signin.maxTimeFieldsignin'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ? 将Redis中的错误次数加1
|
|
|
|
|
|
|
|
await this.redisService.redis.SET(KEY.REDIS_FIELD_SIGNIN_NUM + userId, Number(number) ? Number(number) + 1 : 1, { |
|
|
|
|
|
|
|
PX: waitTime, |
|
|
|
}); |
|
|
|
}); |
|
|
|
throw new HttpException(`用户名或密码错误:${Number(number) + 1}次!`, HttpStatus.BAD_REQUEST); |
|
|
|
throw new HttpException(`用户名或密码错误:${Number(number) + 1}次!`, HttpStatus.BAD_REQUEST); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ! 判断是否是最大登录数
|
|
|
|
// ! 判断是否是最大登录数
|
|
|
|
const clientList = await this.redisService.redis.keys('CLIENT-' + user[0].userId + '-*'); |
|
|
|
// ! 从Redis中获取当前客户端数量,以长Token为准
|
|
|
|
let maxSigninClient = (await this.redisService.get('CONFIG_MAX_SIGNIN_CLIENT')) as any; |
|
|
|
const clientList = await this.redisService.redis.keys(KEY.REDIS_REFRESH_TOKEN + userId + '-*'); |
|
|
|
if (!maxSigninClient) { |
|
|
|
|
|
|
|
maxSigninClient = this.config.get<number>('system.signin.maxSigninClient'); |
|
|
|
// ! 从Redis获取允许的最大客户端数量
|
|
|
|
} |
|
|
|
let maxClient = (await this.redisService.get(KEY.REDIS_MAX_CLIENT)) as any; |
|
|
|
console.log(maxSigninClient, clientList.length >= maxSigninClient) |
|
|
|
|
|
|
|
if (clientList.length >= maxSigninClient) { |
|
|
|
// ? 如果不存在从配置文件取
|
|
|
|
throw new HttpException('已登陆的客户端超过限制!', HttpStatus.BAD_REQUEST); |
|
|
|
maxClient = maxClient ? maxClient : this.config.get<number>('system.signin.maxSigninClient'); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ? 判断当前账户登录数是否超过最大登录数
|
|
|
|
|
|
|
|
if (clientList.length >= maxClient) { |
|
|
|
|
|
|
|
throw new HttpException('已登录的客户端超过限制!', HttpStatus.BAD_REQUEST); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// ! 签发Token
|
|
|
|
// ! 签发Token
|
|
|
|
const token = this.jwt.token({ username: usernameSignInDto.username, userId: user[0].userId, timestamp: new Date().getTime() }); |
|
|
|
// ! 长期Token refreshToken,只用于刷新Token
|
|
|
|
const refreshToken = this.jwt.refreshToken({ username: usernameSignInDto.username, userId: user[0].userId, timestamp: new Date().getTime() }); |
|
|
|
const refreshToken = this.jwt.refreshToken({ |
|
|
|
|
|
|
|
type: 'refreshToken', |
|
|
|
|
|
|
|
username: usernameSignInDto.username, |
|
|
|
|
|
|
|
userId, |
|
|
|
|
|
|
|
timestamp: new Date().getTime(), |
|
|
|
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
// 将登陆的账户放进Redis
|
|
|
|
// ! 短期Token token,用于各种业务请求
|
|
|
|
await this.redisService.redis.set('CLIENT-' + user[0].userId + '-' + MD5(refreshToken), 0, { |
|
|
|
const token = this.jwt.token({ type: 'token', username: usernameSignInDto.username, userId, timestamp: new Date().getTime() }); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// ! 将登录的账户放进Redis
|
|
|
|
|
|
|
|
await this.redisService.redis.set(KEY.REDIS_REFRESH_TOKEN + userId + '-' + MD5(refreshToken), 0, { |
|
|
|
EX: this.config.get<number>('system.signin.refreshTokenTime'), |
|
|
|
EX: this.config.get<number>('system.signin.refreshTokenTime'), |
|
|
|
}); |
|
|
|
}); |
|
|
|
await this.redisService.redis.set('CLIENT-ONLINE-' + user[0].userId + '-' + MD5(token), 0, { |
|
|
|
await this.redisService.redis.set(KEY.REDIS_TOKEN + userId + '-' + MD5(token), 0, { |
|
|
|
EX: this.config.get<number>('system.signin.refreshTokenTime'), |
|
|
|
EX: this.config.get<number>('system.signin.tokenTime'), |
|
|
|
}); |
|
|
|
}); |
|
|
|
|
|
|
|
|
|
|
|
return { |
|
|
|
return { |
|
|
|