完成Token验证

main
expressgy 3 months ago
parent 5e4a81c303
commit ad853c326e
  1. 8
      src/application/app.module.ts
  2. 20
      src/application/auth-dept/auth-dept.controller.ts
  3. 22
      src/application/auth-dept/auth-dept.service.ts
  4. 16
      src/application/auth-post/auth-post.controller.ts
  5. 14
      src/application/auth-post/auth-post.service.ts
  6. 20
      src/application/auth-role/auth-role.controller.ts
  7. 34
      src/application/auth-role/auth-role.service.ts
  8. 42
      src/application/auth-user/auth-user.controller.ts
  9. 3
      src/application/auth-user/auth-user.module.ts
  10. 169
      src/application/auth-user/auth-user.service.ts
  11. 18
      src/application/core-dict/core-dict.controller.ts
  12. 30
      src/application/core-dict/core-dict.service.ts
  13. 18
      src/application/core-env/core-env.controller.ts
  14. 30
      src/application/core-env/core-env.service.ts
  15. 20
      src/application/core-menu/core-menu.controller.ts
  16. 50
      src/application/core-menu/core-menu.service.ts
  17. 16
      src/application/core-service/core-service.controller.ts
  18. 32
      src/application/core-service/core-service.service.ts
  19. 5
      src/application/global.module.ts
  20. 17
      src/common/decorator/pac-info/pac-info.decorator.ts
  21. 82
      src/common/guard/auth/auth.guard.ts
  22. 2
      src/common/service/jwt/jwt.service.ts
  23. 5
      src/config/configuration.ts
  24. 32
      src/utils/key.ts
  25. 2
      src/utils/myType.d.ts

@ -4,7 +4,7 @@ import configuration from '@config/configuration';
import { LogRequestInfoMiddleware } from '@common/middleware/log-request-info/log-request-info.middleware';
import { TestModule } from '@app/test/test.module';
import { UserOperationLogInterceptor } from '@common/interceptor/user-operation-log/user-operation-log.interceptor';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { APP_GUARD, APP_INTERCEPTOR } from '@nestjs/core';
import { AppController } from '@app/app.controller';
import { AppService } from '@app/app.service';
import { UserAgentMiddleware } from '@common/middleware/useragent/useragent.middleware';
@ -18,6 +18,7 @@ import { AuthRoleModule } from './auth-role/auth-role.module';
import { AuthDeptModule } from './auth-dept/auth-dept.module';
import { AuthPostModule } from './auth-post/auth-post.module';
import { AuthUserModule } from './auth-user/auth-user.module';
import { AuthGuard } from '@common/guard/auth/auth.guard';
@Module({
imports: [
@ -49,6 +50,11 @@ import { AuthUserModule } from './auth-user/auth-user.module';
useExisting: UserOperationLogInterceptor,
},
AppService,
{
// 这样写是全局路由守卫,使用APP_GUARD令牌
provide: APP_GUARD,
useClass: AuthGuard,
},
],
})
export class AppModule implements NestModule {

@ -3,8 +3,8 @@ import { AuthDeptService } from './auth-dept.service';
import { CreateAuthDeptDto } from './dto/create-auth-dept.dto';
import { UpdateAuthDeptDto } from './dto/update-auth-dept.dto';
import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator';
import { PacInfoType } from '@utils/myType';
import { UserInfoDecorator } from '@common/decorator/pac-info/pac-info.decorator';
import { GuardInfo } from '@utils/myType';
import { GetAuthDeptDto } from '@app/auth-dept/dto/get-auth-dept.dto';
import { GetUserForAttDto } from '@dto/GetUserForAtt.dto';
import { DeptLinkUserDto } from '@dto/AttLinkUser.dto';
@ -20,8 +20,8 @@ export class AuthDeptController {
})
@ApiProduces('application/json')
@Post()
create(@Body() createAuthDeptDto: CreateAuthDeptDto, @PacInfo() pacInfo: PacInfoType) {
return this.authDeptService.create(createAuthDeptDto, pacInfo);
create(@Body() createAuthDeptDto: CreateAuthDeptDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authDeptService.create(createAuthDeptDto, guardInfo);
}
@ApiOperation({
@ -60,8 +60,8 @@ export class AuthDeptController {
})
@ApiProduces('application/json')
@Patch(':id')
update(@Param('id') id: string, @Body() updateAuthDeptDto: UpdateAuthDeptDto, @PacInfo() pacInfo: PacInfoType) {
return this.authDeptService.update(id, updateAuthDeptDto, pacInfo);
update(@Param('id') id: string, @Body() updateAuthDeptDto: UpdateAuthDeptDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authDeptService.update(id, updateAuthDeptDto, guardInfo);
}
@ApiOperation({
@ -70,8 +70,8 @@ export class AuthDeptController {
})
@ApiProduces('application/json')
@Delete(':id')
remove(@Param('id') id: string, @PacInfo() pacInfo: PacInfoType) {
return this.authDeptService.remove(id, pacInfo);
remove(@Param('id') id: string, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authDeptService.remove(id, guardInfo);
}
@ApiOperation({
@ -90,8 +90,8 @@ export class AuthDeptController {
})
@ApiProduces('application/json')
@Post('/user')
linkUser(@Body() deptLinkUserDto: DeptLinkUserDto, @PacInfo() pacInfo: PacInfoType) {
return this.authDeptService.linkUser(deptLinkUserDto, pacInfo);
linkUser(@Body() deptLinkUserDto: DeptLinkUserDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authDeptService.linkUser(deptLinkUserDto, guardInfo);
}
@ApiOperation({

@ -2,7 +2,7 @@ import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { CreateAuthDeptDto } from './dto/create-auth-dept.dto';
import { UpdateAuthDeptDto } from './dto/update-auth-dept.dto';
import { GetAuthDeptDto } from '@app/auth-dept/dto/get-auth-dept.dto';
import { PacInfoType } from '@utils/myType';
import { GuardInfo } from '@utils/myType';
import { LoggerService } from '@service/logger/logger.service';
import { MysqlService } from '@common/service/mysql/mysql.service';
import { RedisService } from '@common/service/redis/redis.service';
@ -70,7 +70,7 @@ export class AuthDeptService {
* DESC: 创建部门信息
* DATE: 2024-06-25 15:53:04 -
* */
public async create(createAuthDeptDto: CreateAuthDeptDto, pacInfo: PacInfoType) {
public async create(createAuthDeptDto: CreateAuthDeptDto, guardInfo: GuardInfo) {
// ! 加目标锁,同级,而不是全局
const lock = await this.redisService.distributedLock('DEPT' + createAuthDeptDto.pid + '-' + createAuthDeptDto.deptName, createAuthDeptDto.deptName);
@ -95,7 +95,7 @@ export class AuthDeptService {
}
// ! 添加部门数据
const newPacCoreDict = await this.addDeptData(createAuthDeptDto, pGrade + 1, pacInfo.userId);
const newPacCoreDict = await this.addDeptData(createAuthDeptDto, pGrade + 1, guardInfo.userId);
// ! 解锁
lock();
@ -151,7 +151,7 @@ export class AuthDeptService {
* DESC: 更新部门信息
* DATE: 2024-06-28 11:30:50 -
* */
public async update(id: string, updateAuthDeptDto: UpdateAuthDeptDto, pacInfo: PacInfoType) {
public async update(id: string, updateAuthDeptDto: UpdateAuthDeptDto, guardInfo: GuardInfo) {
// ! 获取部门信息
const dept = await this.getDeptForDeptId(id);
@ -177,7 +177,7 @@ export class AuthDeptService {
lock();
// ! 返回结果
return await this.updateDept(id, updateAuthDeptDto, pacInfo.userId);
return await this.updateDept(id, updateAuthDeptDto, guardInfo.userId);
} catch (e) {
// ! 解锁
lock();
@ -192,8 +192,8 @@ export class AuthDeptService {
* DESC: 删除部门信息
* DATE: 2024-06-28 11:30:54 -
* */
public async remove(id: string, pacInfo: PacInfoType) {
return await this.deleteDept(id, pacInfo.userId);
public async remove(id: string, guardInfo: GuardInfo) {
return await this.deleteDept(id, guardInfo.userId);
}
/** Service
@ -210,8 +210,8 @@ export class AuthDeptService {
* DESC: 关联账户给部门
* DATE: 2024-06-28 17:17:16 -
* */
public async linkUser(deptLinkUserDto: DeptLinkUserDto, pacInfo: PacInfoType) {
return this.linkUserForDept(deptLinkUserDto, pacInfo);
public async linkUser(deptLinkUserDto: DeptLinkUserDto, guardInfo: GuardInfo) {
return this.linkUserForDept(deptLinkUserDto, guardInfo);
}
/** Service
@ -550,7 +550,7 @@ export class AuthDeptService {
}
// DB 给部门关联上账户
private async linkUserForDept(deptLinkUserDto: DeptLinkUserDto, pacInfo: PacInfoType) {
private async linkUserForDept(deptLinkUserDto: DeptLinkUserDto, guardInfo: GuardInfo) {
// ! 去重账户ID
const deduplicateUserId = Array.from(new Set(deptLinkUserDto.userIdList));
@ -567,7 +567,7 @@ export class AuthDeptService {
userIdList.map((i) => ({
deptId: deptLinkUserDto.deptId,
userId: i,
createby: pacInfo.userId,
createby: guardInfo.userId,
createtime: sql`now()` as any,
})),
);

@ -3,8 +3,8 @@ import { AuthPostService } from './auth-post.service';
import { CreateAuthPostDto } from './dto/create-auth-post.dto';
import { UpdateAuthPostDto } from './dto/update-auth-post.dto';
import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator';
import { PacInfoType } from '@utils/myType';
import { UserInfoDecorator } from '@common/decorator/pac-info/pac-info.decorator';
import { GuardInfo } from '@utils/myType';
import { GetAuthPostDto } from '@app/auth-post/dto/get-auth-post.dto';
@ApiTags('岗位服务')
@ -18,8 +18,8 @@ export class AuthPostController {
})
@ApiProduces('application/json')
@Post()
create(@Body() createAuthPostDto: CreateAuthPostDto, @PacInfo() pacInfo: PacInfoType) {
return this.authPostService.create(createAuthPostDto, pacInfo);
create(@Body() createAuthPostDto: CreateAuthPostDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authPostService.create(createAuthPostDto, guardInfo);
}
@ApiOperation({
@ -48,8 +48,8 @@ export class AuthPostController {
})
@ApiProduces('application/json')
@Patch(':id')
update(@Param('id') id: string, @Body() updateAuthPostDto: UpdateAuthPostDto, @PacInfo() pacInfo: PacInfoType) {
return this.authPostService.update(id, updateAuthPostDto, pacInfo);
update(@Param('id') id: string, @Body() updateAuthPostDto: UpdateAuthPostDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authPostService.update(id, updateAuthPostDto, guardInfo);
}
@ApiOperation({
@ -58,7 +58,7 @@ export class AuthPostController {
})
@ApiProduces('application/json')
@Delete(':id')
remove(@Param('id') id: string, @PacInfo() pacInfo: PacInfoType) {
return this.authPostService.remove(id, pacInfo);
remove(@Param('id') id: string, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authPostService.remove(id, guardInfo);
}
}

@ -8,7 +8,7 @@ import { Snowflake } from '@service/snowflake/snowflake.service';
import { ConfigService } from '@nestjs/config';
import { pacAuthDept, pacAuthPost, pacAuthUser, pacCoreDict } from '@entities/schema';
import { and, asc, desc, eq, isNull, like, or, sql } from 'drizzle-orm';
import { PacInfoType } from '@utils/myType';
import { GuardInfo } from '@utils/myType';
import { isExistKey, isTrueEnum } from '@utils/boolean.enum';
import { GetAuthPostDto } from '@app/auth-post/dto/get-auth-post.dto';
import { likeQuery } from '@utils/likeQuery';
@ -56,7 +56,7 @@ export class AuthPostService {
* DESC: 创建岗位信息
* DATE: 2024-06-29 13:13:44 -
* */
public async create(createAuthPostDto: CreateAuthPostDto, pacInfo: PacInfoType) {
public async create(createAuthPostDto: CreateAuthPostDto, guardInfo: GuardInfo) {
// ! 加目标锁,同级,而不是全局
const lock = await this.redisService.distributedLock('POST' + createAuthPostDto.postKey, createAuthPostDto.postKey);
@ -73,7 +73,7 @@ export class AuthPostService {
if (result.length > 0) throw new HttpException('岗位标识重复!', HttpStatus.CONFLICT);
// ! 添加岗位数据
const newPacCoreDict = await this.addPost(createAuthPostDto, pacInfo.userId as any);
const newPacCoreDict = await this.addPost(createAuthPostDto, guardInfo.userId as any);
// ! 解锁
lock();
@ -116,8 +116,8 @@ export class AuthPostService {
* DESC: 更新岗位信息
* DATE: 2024-06-29 13:13:52 -
* */
public async update(id: string, updateAuthPostDto: UpdateAuthPostDto, pacInfo: PacInfoType) {
return await this.updatePost(id, updateAuthPostDto, pacInfo.userId as any);
public async update(id: string, updateAuthPostDto: UpdateAuthPostDto, guardInfo: GuardInfo) {
return await this.updatePost(id, updateAuthPostDto, guardInfo.userId as any);
}
/** Service
@ -125,8 +125,8 @@ export class AuthPostService {
* DESC: 删除岗位信息
* DATE: 2024-06-29 13:13:55 -
* */
public remove(id: string, pacInfo: PacInfoType) {
return this.deletePost(id, pacInfo.userId as any);
public remove(id: string, guardInfo: GuardInfo) {
return this.deletePost(id, guardInfo.userId as any);
}
// DB 查重Key

@ -3,8 +3,8 @@ import { AuthRoleService } from './auth-role.service';
import { CreateAuthRoleDto } from './dto/create-auth-role.dto';
import { UpdateAuthRoleDto } from './dto/update-auth-role.dto';
import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator';
import { PacInfoType } from '@utils/myType';
import { UserInfoDecorator } from '@common/decorator/pac-info/pac-info.decorator';
import { GuardInfo } from '@utils/myType';
import { query } from 'express';
import { GetPacAuthRoleAllDto } from '@app/auth-role/dto/get-auth-role.dto';
import { GetUserForAttDto } from '@dto/GetUserForAtt.dto';
@ -21,8 +21,8 @@ export class AuthRoleController {
})
@ApiProduces('application/json')
@Post()
create(@Body() createAuthRoleDto: CreateAuthRoleDto, @PacInfo() pacInfo: PacInfoType) {
return this.authRoleService.create(createAuthRoleDto, pacInfo);
create(@Body() createAuthRoleDto: CreateAuthRoleDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authRoleService.create(createAuthRoleDto, guardInfo);
}
@ApiOperation({
@ -61,8 +61,8 @@ export class AuthRoleController {
})
@ApiProduces('application/json')
@Patch(':id')
update(@Param('id') id: string, @Body() updateAuthRoleDto: UpdateAuthRoleDto, @PacInfo() pacInfo: PacInfoType) {
return this.authRoleService.update(id, updateAuthRoleDto, pacInfo);
update(@Param('id') id: string, @Body() updateAuthRoleDto: UpdateAuthRoleDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authRoleService.update(id, updateAuthRoleDto, guardInfo);
}
@ApiOperation({
@ -71,8 +71,8 @@ export class AuthRoleController {
})
@ApiProduces('application/json')
@Delete(':id')
remove(@Param('id') id: string, @PacInfo() pacInfo: PacInfoType) {
return this.authRoleService.remove(id, pacInfo);
remove(@Param('id') id: string, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authRoleService.remove(id, guardInfo);
}
@ApiOperation({
@ -91,8 +91,8 @@ export class AuthRoleController {
})
@ApiProduces('application/json')
@Post('/user')
linkUser(@Body() roleLinkUserDto: RoleLinkUserDto, @PacInfo() pacInfo: PacInfoType) {
return this.authRoleService.linkUser(roleLinkUserDto, pacInfo);
linkUser(@Body() roleLinkUserDto: RoleLinkUserDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authRoleService.linkUser(roleLinkUserDto, guardInfo);
}
@ApiOperation({

@ -6,7 +6,7 @@ import { MysqlService } from '@common/service/mysql/mysql.service';
import { RedisService } from '@common/service/redis/redis.service';
import { Snowflake } from '@service/snowflake/snowflake.service';
import { ConfigService } from '@nestjs/config';
import { PacInfoType } from '@utils/myType';
import { GuardInfo } from '@utils/myType';
import { isExistKey, isTrueEnum } from '@utils/boolean.enum';
import {
pacAuthDept,
@ -74,9 +74,9 @@ export class AuthRoleService {
* DESC: 创建角色信息
* DATE: 2024-06-25 15:53:04 -
* */
public async create(createAuthRoleDto: CreateAuthRoleDto, pacInfo: PacInfoType) {
public async create(createAuthRoleDto: CreateAuthRoleDto, guardInfo: GuardInfo) {
// ! 判断是否是root账户,非root账户无法设置为root
if (this.config.get<number>('masterId') !== pacInfo.userId && isTrueEnum(createAuthRoleDto.root)) {
if (this.config.get<number>('masterId') !== guardInfo.userId && isTrueEnum(createAuthRoleDto.root)) {
throw new HttpException('没有权限创建原始角色!', HttpStatus.UNAUTHORIZED);
}
@ -95,20 +95,20 @@ export class AuthRoleService {
if (result.length > 0) throw new HttpException('角色标识重复!', HttpStatus.CONFLICT);
// ! 添加角色数据
const newRoleResult = await this.addRoleData(createAuthRoleDto, pacInfo.userId).catch((e) => {
const newRoleResult = await this.addRoleData(createAuthRoleDto, guardInfo.userId).catch((e) => {
this.logger.error(e.message + e.track.toString());
throw new HttpException('角色写入错误!', HttpStatus.INTERNAL_SERVER_ERROR);
});
// ! 增加关联菜单
await this.createMenuLink(newRoleResult.roleId, createAuthRoleDto.menuList, pacInfo.userId as any).catch((e) => {
await this.createMenuLink(newRoleResult.roleId, createAuthRoleDto.menuList, guardInfo.userId as any).catch((e) => {
this.logger.error(e.message + e.track.toString());
throw new HttpException('添加菜单关系出现错误,角色写入错误!', HttpStatus.INTERNAL_SERVER_ERROR);
});
// ! 增加关联部门
if (createAuthRoleDto.deptScope == 5) {
await this.createDeptLink(newRoleResult.roleId, createAuthRoleDto.deptList, pacInfo.userId as any).catch((e) => {
await this.createDeptLink(newRoleResult.roleId, createAuthRoleDto.deptList, guardInfo.userId as any).catch((e) => {
this.logger.error(e.message + e.track.toString());
throw new HttpException('添加部门数据范围关系出现错误,角色写入错误!', HttpStatus.INTERNAL_SERVER_ERROR);
});
@ -172,7 +172,7 @@ export class AuthRoleService {
return await this.getRoleUser(roleId, getUserForRoleDto);
}
public async update(roleId: string, updateAuthRoleDto: UpdateAuthRoleDto, pacInfo: PacInfoType) {
public async update(roleId: string, updateAuthRoleDto: UpdateAuthRoleDto, guardInfo: GuardInfo) {
// ! 查找角色信息
const roleData = await this.getRoleForRoleId(roleId);
@ -182,7 +182,7 @@ export class AuthRoleService {
}
// ! 判断是否是root账户,非root账户无法设置为root
if (this.config.get('masterId') !== pacInfo.userId && isTrueEnum(roleData[0].root)) {
if (this.config.get('masterId') !== guardInfo.userId && isTrueEnum(roleData[0].root)) {
throw new HttpException('没有权限创建原始角色!', HttpStatus.UNAUTHORIZED);
}
@ -201,19 +201,19 @@ export class AuthRoleService {
if (checkRepeat.length > 0 && checkRepeat[0].id != roleId) throw new HttpException('角色标识重复!', HttpStatus.CONFLICT);
// ! 修改角色数据
const result = await this.updateRole(roleId, updateAuthRoleDto, pacInfo.userId as any).catch((e) => {
const result = await this.updateRole(roleId, updateAuthRoleDto, guardInfo.userId as any).catch((e) => {
this.logger.error(e.message + e.track.toString());
throw new HttpException('角色写入错误!', HttpStatus.INTERNAL_SERVER_ERROR);
});
// ! 增加关联菜单
await this.createMenuLink(roleData[0].roleId, updateAuthRoleDto.menuList, pacInfo.userId as any).catch((e) => {
await this.createMenuLink(roleData[0].roleId, updateAuthRoleDto.menuList, guardInfo.userId as any).catch((e) => {
this.logger.error(e.message + e.track.toString());
throw new HttpException('添加菜单关系出现错误,角色写入错误!', HttpStatus.INTERNAL_SERVER_ERROR);
});
// ! 增加关联部门
await this.createDeptLink(roleData[0].roleId, updateAuthRoleDto.deptList, pacInfo.userId as any).catch((e) => {
await this.createDeptLink(roleData[0].roleId, updateAuthRoleDto.deptList, guardInfo.userId as any).catch((e) => {
this.logger.error(e.message + e.track);
throw new HttpException('添加部门数据范围关系出现错误,角色写入错误!', HttpStatus.INTERNAL_SERVER_ERROR);
});
@ -237,8 +237,8 @@ export class AuthRoleService {
* DESC: 删除角色信息
* DATE: 2024-06-26 16:16:55 -
* */
public async remove(roleId: string, pacInfo: PacInfoType) {
return await this.deleteRole(roleId, pacInfo.userId as any);
public async remove(roleId: string, guardInfo: GuardInfo) {
return await this.deleteRole(roleId, guardInfo.userId as any);
}
/** Service
@ -246,8 +246,8 @@ export class AuthRoleService {
* DESC: 关联账户给角色
* DATE: 2024-06-27 15:38:50 -
* */
public async linkUser(roleLinkUserDto: RoleLinkUserDto, pacInfo: PacInfoType) {
return this.linkUserForRole(roleLinkUserDto, pacInfo);
public async linkUser(roleLinkUserDto: RoleLinkUserDto, guardInfo: GuardInfo) {
return this.linkUserForRole(roleLinkUserDto, guardInfo);
}
/** Service
@ -660,7 +660,7 @@ export class AuthRoleService {
}
// DB 给角色关联上账户
private async linkUserForRole(roleLinkUserDto: RoleLinkUserDto, pacInfo: PacInfoType) {
private async linkUserForRole(roleLinkUserDto: RoleLinkUserDto, guardInfo: GuardInfo) {
// ! 去重账户ID
const deduplicateUserId = Array.from(new Set(roleLinkUserDto.userIdList));
@ -677,7 +677,7 @@ export class AuthRoleService {
userIdList.map((i) => ({
roleId: roleLinkUserDto.roleId,
userId: i,
createby: pacInfo.userId,
createby: guardInfo.userId,
createtime: sql`now()` as any,
})),
);

@ -3,12 +3,12 @@ import { AuthUserService } from './auth-user.service';
import { CreateAuthUserDto } from './dto/create-auth-user.dto';
import { UpdateAuthUserDto } from './dto/update-auth-user.dto';
import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator';
import { PacInfoType } from '@utils/myType';
import { UserInfoDecorator } from '@common/decorator/pac-info/pac-info.decorator';
import { GuardInfo } from '@utils/myType';
import { GetPacAuthUserAllDto } from '@app/auth-user/dto/get-auth-user.dto';
import { PasswordDto } from '@app/auth-user/dto/password.dto';
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';
@ApiTags('账户服务')
@Controller('authUser')
@ -21,8 +21,8 @@ export class AuthUserController {
})
@ApiProduces('application/json')
@Post()
create(@Body() createAuthUserDto: CreateAuthUserDto, @PacInfo() pacInfo: PacInfoType) {
return this.authUserService.create(createAuthUserDto, pacInfo);
create(@Body() createAuthUserDto: CreateAuthUserDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authUserService.create(createAuthUserDto, guardInfo);
}
@ApiOperation({
@ -51,8 +51,8 @@ export class AuthUserController {
})
@ApiProduces('application/json')
@Patch(':id')
update(@Param('id') id: string, @Body() updateAuthUserDto: UpdateAuthUserDto, @PacInfo() pacInfo: PacInfoType) {
return this.authUserService.update(id, updateAuthUserDto, pacInfo);
update(@Param('id') id: string, @Body() updateAuthUserDto: UpdateAuthUserDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authUserService.update(id, updateAuthUserDto, guardInfo);
}
@ApiOperation({
@ -61,8 +61,8 @@ export class AuthUserController {
})
@ApiProduces('application/json')
@Delete(':id')
remove(@Param('id') id: string, @PacInfo() pacInfo: PacInfoType) {
return this.authUserService.remove(id, pacInfo);
remove(@Param('id') id: string, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authUserService.remove(id, guardInfo);
}
@ApiOperation({
@ -91,8 +91,8 @@ export class AuthUserController {
})
@ApiProduces('application/json')
@Patch('/role/:id')
updateLinkRole(@Param('id') id: string, @Body() updateLinkDto: UpdateLinkDto, @PacInfo() pacInfo: PacInfoType) {
return this.authUserService.updateLinkRole(id, updateLinkDto, pacInfo);
updateLinkRole(@Param('id') id: string, @Body() updateLinkDto: UpdateLinkDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authUserService.updateLinkRole(id, updateLinkDto, guardInfo);
}
@ApiOperation({
@ -101,8 +101,8 @@ export class AuthUserController {
})
@ApiProduces('application/json')
@Patch('/dept/:id')
updateLinkDept(@Param('id') id: string, @Body() updateLinkDto: UpdateLinkDto, @PacInfo() pacInfo: PacInfoType) {
return this.authUserService.updateLinkDept(id, updateLinkDto, pacInfo);
updateLinkDept(@Param('id') id: string, @Body() updateLinkDto: UpdateLinkDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authUserService.updateLinkDept(id, updateLinkDto, guardInfo);
}
@ApiOperation({
@ -111,8 +111,8 @@ export class AuthUserController {
})
@ApiProduces('application/json')
@Patch('/post/:id')
updateLinkPost(@Param('id') id: string, @Body() updateLinkDto: UpdateLinkDto, @PacInfo() pacInfo: PacInfoType) {
return this.authUserService.updateLinkPost(id, updateLinkDto, pacInfo);
updateLinkPost(@Param('id') id: string, @Body() updateLinkDto: UpdateLinkDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.authUserService.updateLinkPost(id, updateLinkDto, guardInfo);
}
@ApiOperation({
@ -120,8 +120,18 @@ export class AuthUserController {
description: '登陆系统',
})
@ApiProduces('application/json')
@Post('/signin')
@Post('/sign/in')
signin(@Body() usernameSignInDto: UsernameSignInDto) {
return this.authUserService.signin(usernameSignInDto);
}
@ApiOperation({
summary: '登陆系统',
description: '登陆系统',
})
@ApiProduces('application/json')
@Post('/sign/refresh')
refreshToken(@UserInfoDecorator() guardInfo: GuardInfo) {
return this.authUserService.refreshToken(guardInfo);
}
}

@ -1,10 +1,9 @@
import { Module } from '@nestjs/common';
import { AuthUserService } from './auth-user.service';
import { AuthUserController } from './auth-user.controller';
import { JwtService } from '@common/service/jwt/jwt.service';
@Module({
controllers: [AuthUserController],
providers: [AuthUserService, JwtService],
providers: [AuthUserService],
})
export class AuthUserModule {}

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

@ -3,8 +3,8 @@ import { CoreDictService } from './core-dict.service';
import { CreateCoreDictDto } from './dto/create-core-dict.dto';
import { UpdateCoreDictDto } from './dto/update-core-dict.dto';
import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator';
import { PacInfoType } from '@utils/myType';
import { UserInfoDecorator } from '@common/decorator/pac-info/pac-info.decorator';
import { GuardInfo } from '@utils/myType';
import { GetPacCoreDictAllDto, PacCoreDictTargetListDto } from '@app/core-dict/dto/get-core-dict.dto';
@ApiTags('字典服务')
@ -18,8 +18,8 @@ export class CoreDictController {
})
@ApiProduces('application/json')
@Post()
create(@Body() createCoreDictDto: CreateCoreDictDto, @PacInfo() pacInfo: PacInfoType) {
return this.coreDictService.create(createCoreDictDto, pacInfo);
create(@Body() createCoreDictDto: CreateCoreDictDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.coreDictService.create(createCoreDictDto, guardInfo);
}
@ApiOperation({
@ -28,7 +28,7 @@ export class CoreDictController {
})
@ApiProduces('application/json')
@Get()
findAll(@Query() getCoreDictAllDto: GetPacCoreDictAllDto, @PacInfo() pacInfo: PacInfoType) {
findAll(@Query() getCoreDictAllDto: GetPacCoreDictAllDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.coreDictService.findAll(getCoreDictAllDto);
}
@ -58,8 +58,8 @@ export class CoreDictController {
})
@ApiProduces('application/json')
@Patch(':dictId')
update(@Param('dictId') dictId: string, @Body() updateCoreDictDto: UpdateCoreDictDto, @PacInfo() pacInfo: PacInfoType) {
return this.coreDictService.update(dictId, updateCoreDictDto, pacInfo);
update(@Param('dictId') dictId: string, @Body() updateCoreDictDto: UpdateCoreDictDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.coreDictService.update(dictId, updateCoreDictDto, guardInfo);
}
@ApiOperation({
@ -68,7 +68,7 @@ export class CoreDictController {
})
@ApiProduces('application/json')
@Delete(':dictId')
remove(@Param('dictId') dictId: string, @PacInfo() pacInfo: PacInfoType) {
return this.coreDictService.remove(dictId, pacInfo);
remove(@Param('dictId') dictId: string, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.coreDictService.remove(dictId, guardInfo);
}
}

@ -11,7 +11,7 @@ import { GetPacCoreDictAllDto, PacCoreDictTargetListDto } from '@app/core-dict/d
import { ConfigService } from '@nestjs/config';
import { likeQuery } from '@utils/likeQuery';
import { alias, QueryBuilder } from 'drizzle-orm/mysql-core';
import { PacInfoType } from '@utils/myType';
import { GuardInfo } from '@utils/myType';
import { isTrueEnum, isExistKey } from '@utils/boolean.enum';
import { customDrizzleRowWithRecursive } from '@utils/customDrizzleRowWithRecursive';
@ -63,9 +63,9 @@ export class CoreDictService {
* DESC: 创建字典内容
* DATE: 2024-05-31 19:12:47 -
* */
public async create(createCoreDictDto: CreateCoreDictDto, pacInfo: PacInfoType) {
public async create(createCoreDictDto: CreateCoreDictDto, guardInfo: GuardInfo) {
// ! 判断是否是root账户,非root账户无法设置为root
if (this.config.get<number>('masterId') !== pacInfo.userId && isTrueEnum(createCoreDictDto.root)) {
if (this.config.get<number>('masterId') !== guardInfo.userId && isTrueEnum(createCoreDictDto.root)) {
throw new HttpException('没有权限创建原始字典!', HttpStatus.UNAUTHORIZED);
}
@ -84,7 +84,7 @@ export class CoreDictService {
if (result.length > 0) throw new HttpException('字典标识重复!', HttpStatus.CONFLICT);
// ! 添加字典数据
const newPacCoreDict = await this.addDictData(createCoreDictDto, pacInfo.userId);
const newPacCoreDict = await this.addDictData(createCoreDictDto, guardInfo.userId);
// ! 解锁
lock();
@ -145,9 +145,9 @@ export class CoreDictService {
* DESC: 更新字典
* DATE: 2024-06-04 23:24:18 -
* */
public async update(dictId: string, updateCoreDictDto: UpdateCoreDictDto, pacInfo: PacInfoType) {
public async update(dictId: string, updateCoreDictDto: UpdateCoreDictDto, guardInfo: GuardInfo) {
// ! 判断是否是root账户,非root账户无法设置为root
if (this.config.get<number>('masterId') !== pacInfo.userId && updateCoreDictDto.root !== undefined) {
if (this.config.get<number>('masterId') !== guardInfo.userId && updateCoreDictDto.root !== undefined) {
throw new HttpException('没有权限修改原始字典!', HttpStatus.UNAUTHORIZED);
}
@ -156,7 +156,7 @@ export class CoreDictService {
if (oldDict.length == 0) throw new HttpException('未找到目标字典,无法修改!', HttpStatus.BAD_REQUEST);
// ! root数据,非root用户不允许修改
if (oldDict[0].root && this.config.get<number>('masterId') !== pacInfo.userId) {
if (oldDict[0].root && this.config.get<number>('masterId') !== guardInfo.userId) {
throw new HttpException('原始字典,权限不足无法修改!', HttpStatus.BAD_REQUEST);
}
@ -177,7 +177,7 @@ export class CoreDictService {
}
// ! 更新数据
const result = await this.updateDictData(dictId, updateCoreDictDto, pacInfo);
const result = await this.updateDictData(dictId, updateCoreDictDto, guardInfo);
// ! 解锁
lock();
@ -198,7 +198,7 @@ export class CoreDictService {
* DESC: 删除字典
* DATE: 2024-06-04 22:01:11 -
* */
public async remove(dictId: string, pacInfo: PacInfoType) {
public async remove(dictId: string, guardInfo: GuardInfo) {
// ! 查看目标字典项
const result = await this.getMore(dictId);
@ -208,7 +208,7 @@ export class CoreDictService {
}
// ! root数据,非root用户不允许删除
if (result[0].root && this.config.get<number>('masterId') !== pacInfo.userId) {
if (result[0].root && this.config.get<number>('masterId') !== guardInfo.userId) {
throw new HttpException('原始字典,权限不足无法删除!', HttpStatus.BAD_REQUEST);
}
@ -217,7 +217,7 @@ export class CoreDictService {
// ? 判断是否存在子项
if (result[0].haveChildren == 0) {
// ! 删除字典
await this.deleteDictItem(dictId, pacInfo);
await this.deleteDictItem(dictId, guardInfo);
} else {
throw new HttpException('该字典存在子项!', HttpStatus.BAD_REQUEST);
}
@ -409,18 +409,18 @@ export class CoreDictService {
}
// DB 通过ID删除字典项
private deleteDictItem(dictId: string, pacInfo: PacInfoType) {
private deleteDictItem(dictId: string, guardInfo: GuardInfo) {
return this.mysqlService.db
.update(pacCoreDict)
.set({
deletetime: sql`now()`,
deleteby: pacInfo.userId,
deleteby: guardInfo.userId,
})
.where(eq(pacCoreDict.dictId, dictId));
}
// DB 更新字典
private updateDictData(dictId: string, updateCoreDictDto: UpdateCoreDictDto, pacInfo: PacInfoType) {
private updateDictData(dictId: string, updateCoreDictDto: UpdateCoreDictDto, guardInfo: GuardInfo) {
return this.mysqlService.db
.update(pacCoreDict)
.set({
@ -433,7 +433,7 @@ export class CoreDictService {
status: updateCoreDictDto.status,
root: isTrueEnum(updateCoreDictDto.root) ? 1 : 0,
serviceKey: updateCoreDictDto.serviceKey,
updateby: pacInfo.userId,
updateby: guardInfo.userId,
updatetime: sql`now()`,
})
.where(eq(pacCoreDict.dictId, dictId));

@ -3,8 +3,8 @@ import { CoreEnvService } from './core-env.service';
import { CreateCoreEnvDto } from './dto/create-core-env.dto';
import { UpdateCoreEnvDto } from './dto/update-core-env.dto';
import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator';
import { PacInfoType } from '@utils/myType';
import { UserInfoDecorator } from '@common/decorator/pac-info/pac-info.decorator';
import { GuardInfo } from '@utils/myType';
import { CoreEnvKeyDTO, CoreEnvTargetListDTO, GetCoreEnvDTO } from '@app/core-env/dto/get-core-env.dto';
@ApiTags('环境变量服务')
@ -18,8 +18,8 @@ export class CoreEnvController {
})
@ApiProduces('application/json')
@Post()
create(@Body() createCoreEnvDto: CreateCoreEnvDto, @PacInfo() pacInfo: PacInfoType) {
return this.coreEnvService.create(createCoreEnvDto, pacInfo);
create(@Body() createCoreEnvDto: CreateCoreEnvDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.coreEnvService.create(createCoreEnvDto, guardInfo);
}
@ApiOperation({
@ -28,7 +28,7 @@ export class CoreEnvController {
})
@ApiProduces('application/json')
@Get()
findAll(@Query() getCoreEnvDTO: GetCoreEnvDTO, @PacInfo() pacInfo: PacInfoType) {
findAll(@Query() getCoreEnvDTO: GetCoreEnvDTO, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.coreEnvService.findAll(getCoreEnvDTO);
}
@ -58,8 +58,8 @@ export class CoreEnvController {
})
@ApiProduces('application/json')
@Patch(':envId')
update(@Param('envId') envId: string, @Body() updateCoreEnvDto: UpdateCoreEnvDto, @PacInfo() pacInfo: PacInfoType) {
return this.coreEnvService.update(envId, updateCoreEnvDto, pacInfo);
update(@Param('envId') envId: string, @Body() updateCoreEnvDto: UpdateCoreEnvDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.coreEnvService.update(envId, updateCoreEnvDto, guardInfo);
}
@ApiOperation({
@ -68,7 +68,7 @@ export class CoreEnvController {
})
@ApiProduces('application/json')
@Delete(':envId')
remove(@Param('envId') envId: string, @PacInfo() pacInfo: PacInfoType) {
return this.coreEnvService.remove(envId, pacInfo);
remove(@Param('envId') envId: string, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.coreEnvService.remove(envId, guardInfo);
}
}

@ -13,7 +13,7 @@ import { CoreEnvKeyDTO, CoreEnvTargetListDTO, GetCoreEnvDTO } from '@app/core-en
import { likeQuery } from '@utils/likeQuery';
import { QueryBuilder, alias } from 'drizzle-orm/mysql-core';
import { customDrizzleRowWithRecursive } from '@utils/customDrizzleRowWithRecursive';
import { PacInfoType } from '@utils/myType';
import { GuardInfo } from '@utils/myType';
@Injectable()
export class CoreEnvService {
@ -70,9 +70,9 @@ export class CoreEnvService {
* DESC: 创建环境变量内容
* DATE: 2024-06-05 11:48:04 -
* */
public async create(createCoreEnvDto: CreateCoreEnvDto, pacInfo: PacInfoType) {
public async create(createCoreEnvDto: CreateCoreEnvDto, guardInfo: GuardInfo) {
// ! 判断是否是root账户,非root账户无法设置为root
if (this.config.get<number>('masterId') !== pacInfo.userId && isTrueEnum(createCoreEnvDto.root)) {
if (this.config.get<number>('masterId') !== guardInfo.userId && isTrueEnum(createCoreEnvDto.root)) {
throw new HttpException('没有权限创建原始变量!', HttpStatus.UNAUTHORIZED);
}
@ -91,7 +91,7 @@ export class CoreEnvService {
if (result.length > 0) throw new HttpException('环境变量标识重复!', HttpStatus.CONFLICT);
// ! 添加环境变量数据
const newPacCoreEnv = await this.addEnvData(createCoreEnvDto, pacInfo);
const newPacCoreEnv = await this.addEnvData(createCoreEnvDto, guardInfo);
// ! 解锁
lock();
@ -145,9 +145,9 @@ export class CoreEnvService {
return result;
}
public async update(envId: string, updateCoreEnvDto: UpdateCoreEnvDto, pacInfo: PacInfoType) {
public async update(envId: string, updateCoreEnvDto: UpdateCoreEnvDto, guardInfo: GuardInfo) {
// ! 判断是否是root账户,非root账户无法设置为root
if (this.config.get<number>('masterId') !== pacInfo.userId && updateCoreEnvDto.root !== undefined) {
if (this.config.get<number>('masterId') !== guardInfo.userId && updateCoreEnvDto.root !== undefined) {
throw new HttpException('没有权限修改原始字典!', HttpStatus.UNAUTHORIZED);
}
@ -158,7 +158,7 @@ export class CoreEnvService {
}
// ! root数据,非root用户不允许修改
if (oldEnv[0].root && this.config.get<number>('masterId') !== pacInfo.userId) {
if (oldEnv[0].root && this.config.get<number>('masterId') !== guardInfo.userId) {
throw new HttpException('原始变量,权限不足无法修改!', HttpStatus.BAD_REQUEST);
}
@ -179,7 +179,7 @@ export class CoreEnvService {
}
// ! 更新数据
const result = await this.updateEnvData(envId, updateCoreEnvDto, pacInfo);
const result = await this.updateEnvData(envId, updateCoreEnvDto, guardInfo);
// ! 解锁
lock();
@ -200,14 +200,14 @@ export class CoreEnvService {
* DESC: 删除环境变量
* DATE: 2024-06-05 17:17:28 -
* */
public async remove(envId: string, pacInfo: PacInfoType) {
public async remove(envId: string, guardInfo: GuardInfo) {
// ! 查看目标环境变量
const result = await this.getMore(envId);
// ? 判断是否存在
if (result.length > 0) {
// ! root数据,非root用户不允许删除
if (result[0].root && this.config.get<number>('masterId') !== pacInfo.userId) {
if (result[0].root && this.config.get<number>('masterId') !== guardInfo.userId) {
throw new HttpException('原始变量,权限不足无法删除!', HttpStatus.BAD_REQUEST);
}
@ -216,7 +216,7 @@ export class CoreEnvService {
// ? 判断是否存在子项
if (result[0].haveChildren == 0) {
// ! 删除目标环境变量
await this.deleteEnvItem(envId, pacInfo);
await this.deleteEnvItem(envId, guardInfo);
} else {
throw new HttpException('目标环境变量存在子项!', HttpStatus.BAD_REQUEST);
}
@ -424,18 +424,18 @@ export class CoreEnvService {
}
// DB 通过ID删除Env
private deleteEnvItem(envId: string, pacInfo: PacInfoType) {
private deleteEnvItem(envId: string, guardInfo: GuardInfo) {
return this.mysqlService.db
.update(pacCoreEnv)
.set({
deletetime: sql`now()`,
deleteby: pacInfo.userId,
deleteby: guardInfo.userId,
})
.where(eq(pacCoreEnv.envId, envId));
}
// DB 更新Env
private updateEnvData(envId: string, updateCoreEnvDto: UpdateCoreEnvDto, pacInfo: PacInfoType) {
private updateEnvData(envId: string, updateCoreEnvDto: UpdateCoreEnvDto, guardInfo: GuardInfo) {
return this.mysqlService.db
.update(pacCoreEnv)
.set({
@ -448,7 +448,7 @@ export class CoreEnvService {
orderNum: updateCoreEnvDto.orderNum,
status: updateCoreEnvDto.status,
serviceKey: updateCoreEnvDto.serviceKey,
updateby: pacInfo.userId,
updateby: guardInfo.userId,
updatetime: sql`now()`,
})
.where(eq(pacCoreEnv.envId, envId));

@ -3,8 +3,8 @@ import { CoreMenuService } from './core-menu.service';
import { CreateCoreMenuDto } from './dto/create-core-menu.dto';
import { UpdateCoreMenuDto } from './dto/update-core-menu.dto';
import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator';
import { PacInfoType } from '@utils/myType';
import { UserInfoDecorator } from '@common/decorator/pac-info/pac-info.decorator';
import { GuardInfo } from '@utils/myType';
import { GetPacCoreMenuAllDto } from '@app/core-menu/dto/get-core-menu.dto';
@ApiTags('菜单服务')
@ -18,8 +18,8 @@ export class CoreMenuController {
})
@ApiProduces('application/json')
@Post()
create(@Body() createCoreMenuDto: CreateCoreMenuDto, @PacInfo() pacInfo: PacInfoType) {
return this.coreMenuService.create(createCoreMenuDto, pacInfo);
create(@Body() createCoreMenuDto: CreateCoreMenuDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.coreMenuService.create(createCoreMenuDto, guardInfo);
}
@ApiOperation({
@ -28,8 +28,8 @@ export class CoreMenuController {
})
@ApiProduces('application/json')
@Get()
findAll(@Query() getPacCoreMenuAllDto: GetPacCoreMenuAllDto, @PacInfo() pacInfo: PacInfoType) {
return this.coreMenuService.findAll(getPacCoreMenuAllDto, pacInfo);
findAll(@Query() getPacCoreMenuAllDto: GetPacCoreMenuAllDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.coreMenuService.findAll(getPacCoreMenuAllDto, guardInfo);
}
@ApiOperation({
@ -38,8 +38,8 @@ export class CoreMenuController {
})
@ApiProduces('application/json')
@Patch(':menuId')
update(@Param('menuId') id: string, @Body() updateCoreMenuDto: UpdateCoreMenuDto, @PacInfo() pacInfo: PacInfoType) {
return this.coreMenuService.update(id, updateCoreMenuDto, pacInfo);
update(@Param('menuId') id: string, @Body() updateCoreMenuDto: UpdateCoreMenuDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.coreMenuService.update(id, updateCoreMenuDto, guardInfo);
}
@ApiOperation({
@ -48,7 +48,7 @@ export class CoreMenuController {
})
@ApiProduces('application/json')
@Delete(':menuId')
remove(@Param('menuId') id: string, @PacInfo() pacInfo: PacInfoType) {
return this.coreMenuService.remove(id, pacInfo);
remove(@Param('menuId') id: string, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.coreMenuService.remove(id, guardInfo);
}
}

@ -6,7 +6,7 @@ import { MysqlService } from '@common/service/mysql/mysql.service';
import { RedisService } from '@common/service/redis/redis.service';
import { Snowflake } from '@service/snowflake/snowflake.service';
import { ConfigService } from '@nestjs/config';
import { PacInfoType } from '@utils/myType';
import { GuardInfo } from '@utils/myType';
import { pacAuthUser, pacCoreDict, pacCoreMenu, pacCoreService } from '@entities/schema';
import { eq, sql, isNull, asc, desc, or, like, and } from 'drizzle-orm';
import { isExistKey, isTrueEnum } from '@utils/boolean.enum';
@ -77,16 +77,16 @@ export class CoreMenuService {
* DESC: 创建菜单内容
* DATE: 2024-06-22 17:57:15 -
* */
public async create(createCoreMenuDto: CreateCoreMenuDto, pacInfo: PacInfoType) {
public async create(createCoreMenuDto: CreateCoreMenuDto, guardInfo: GuardInfo) {
// ! 加目标锁,允许同名,所以就不加锁了
// ? 判断是不是pac,不是的话直接退出
if (this.config.get<number>('masterId') !== pacInfo.userId) {
if (this.config.get<number>('masterId') !== guardInfo.userId) {
throw new HttpException('没有权限添加菜单!', HttpStatus.UNAUTHORIZED);
}
// ! 执行写入
const newPacCoreMenu = await this.addMenuData(createCoreMenuDto, pacInfo);
const newPacCoreMenu = await this.addMenuData(createCoreMenuDto, guardInfo);
// ? 判断是否存在pid,对pid的haveChildren进行变化
await this.haveChildrenSelfIncreasing(createCoreMenuDto.pid);
@ -98,29 +98,29 @@ export class CoreMenuService {
* DESC: 获取菜单列表/
* DATE: 2024-06-22 18:21:57 -
* */
public async findAll(getPacCoreMenuAllDto: GetPacCoreMenuAllDto, pacInfo: PacInfoType) {
public async findAll(getPacCoreMenuAllDto: GetPacCoreMenuAllDto, guardInfo: GuardInfo) {
// ? 是否查询列表
if (isExistKey(getPacCoreMenuAllDto, 'isList') && isTrueEnum(getPacCoreMenuAllDto['isList'])) {
// ! 返回列表数据
return await this.getMenuList(getPacCoreMenuAllDto, pacInfo);
return await this.getMenuList(getPacCoreMenuAllDto, guardInfo);
} else {
// ! 返回分页数据
return await this.getMenuPage(getPacCoreMenuAllDto, pacInfo);
return await this.getMenuPage(getPacCoreMenuAllDto, guardInfo);
}
}
public update(id: string, updateCoreMenuDto: UpdateCoreMenuDto, pacInfo: PacInfoType) {
public update(id: string, updateCoreMenuDto: UpdateCoreMenuDto, guardInfo: GuardInfo) {
// ! 比较权限
if (this.config.get<number>('masterId') !== pacInfo.userId) {
if (this.config.get<number>('masterId') !== guardInfo.userId) {
throw new HttpException('没有权限删除菜单!', HttpStatus.UNAUTHORIZED);
}
// ! 写入数据
}
public async remove(id: string, pacInfo: PacInfoType) {
public async remove(id: string, guardInfo: GuardInfo) {
// ! 比较权限
if (this.config.get<number>('masterId') !== pacInfo.userId) {
if (this.config.get<number>('masterId') !== guardInfo.userId) {
throw new HttpException('没有权限删除菜单!', HttpStatus.UNAUTHORIZED);
}
@ -131,7 +131,7 @@ export class CoreMenuService {
}
// ! 执行删除
await this.deleteMenuItem(id, pacInfo);
await this.deleteMenuItem(id, guardInfo);
// ! 更改发节点的子节点数
if (result[0].pid != 0) {
@ -142,7 +142,7 @@ export class CoreMenuService {
}
// DB 增加菜单
async addMenuData(createCoreMenuDto: CreateCoreMenuDto, pacInfo: PacInfoType) {
async addMenuData(createCoreMenuDto: CreateCoreMenuDto, guardInfo: GuardInfo) {
// ! 生成雪花id,用于字典主键
const id = await this.snowflake.generate();
@ -161,7 +161,7 @@ export class CoreMenuService {
isActivate: isTrueEnum(createCoreMenuDto.isActivate) ? 0 : 1,
orderNum: createCoreMenuDto.orderNum,
serviceKey: createCoreMenuDto.serviceKey,
createby: pacInfo.userId,
createby: guardInfo.userId,
createtime: sql`now()` as any,
};
@ -179,7 +179,7 @@ export class CoreMenuService {
}
// DB 查菜单数据
private getMenuData(data: GetPacCoreMenuAllDto, pacInfo: PacInfoType, selectData = undefined) {
private getMenuData(data: GetPacCoreMenuAllDto, guardInfo: GuardInfo, selectData = undefined) {
// ! 定义基础查询函数
// 启用动态查询模式 $dynamic
const query = this.mysqlService.db
@ -223,7 +223,7 @@ export class CoreMenuService {
wl.push(eq(pacCoreMenu.status, data.status as any).if(isExistKey(data, 'status')));
// ? 判断是否是pac查的
if (this.config.get<number>('masterId') === pacInfo.userId) {
if (this.config.get<number>('masterId') === guardInfo.userId) {
// ? 是否要按照激活查
if (isExistKey(data, 'isActivate')) {
wl.push(eq(pacCoreMenu.isActivate, isTrueEnum(data['isActivate']) ? 0 : 1));
@ -238,23 +238,23 @@ export class CoreMenuService {
}
// DB 查列表数据
private getMenuList(getMenuData: GetPacCoreMenuAllDto, pacInfo: PacInfoType) {
return this.getMenuData(getMenuData, pacInfo, this.menuListDataType);
private getMenuList(getMenuData: GetPacCoreMenuAllDto, guardInfo: GuardInfo) {
return this.getMenuData(getMenuData, guardInfo, this.menuListDataType);
}
// DB查分页数据
private async getMenuPage(getPacCoreMenuAllDto: GetPacCoreMenuAllDto, pacInfo: PacInfoType) {
private async getMenuPage(getPacCoreMenuAllDto: GetPacCoreMenuAllDto, guardInfo: GuardInfo) {
const offset = (getPacCoreMenuAllDto.pageNumber - 1) * getPacCoreMenuAllDto.pageSize;
// 使用基础查询构建查询总记录数
const totalCountQuery = this.getMenuData(getPacCoreMenuAllDto, pacInfo, {
const totalCountQuery = this.getMenuData(getPacCoreMenuAllDto, guardInfo, {
totalCount: sql`COUNT(*)`,
});
// 使用基础查询构建分页查询
// 重命名表
const userTable1 = alias(pacAuthUser, 'userTable1');
const paginatedQuery = this.getMenuData(getPacCoreMenuAllDto, pacInfo, { ...this.menuMoreDataType, createName: userTable1.nickname })
const paginatedQuery = this.getMenuData(getPacCoreMenuAllDto, guardInfo, { ...this.menuMoreDataType, createName: userTable1.nickname })
.leftJoin(pacAuthUser, eq(pacCoreMenu.createby, pacAuthUser.userId))
.leftJoin(userTable1, eq(pacCoreMenu.updateby, userTable1.userId))
.limit(getPacCoreMenuAllDto.pageSize)
@ -268,12 +268,12 @@ export class CoreMenuService {
}
// DB 删除菜单
private deleteMenuItem(id, pacInfo: PacInfoType) {
private deleteMenuItem(id, guardInfo: GuardInfo) {
return this.mysqlService.db
.update(pacCoreMenu)
.set({
deletetime: sql`now()`,
deleteby: pacInfo.userId,
deleteby: guardInfo.userId,
})
.where(eq(pacCoreMenu.menuId, id));
}
@ -290,7 +290,7 @@ export class CoreMenuService {
}
// DB 更新菜单信息
private async updateMenuData(id, updateCoreMenuDto: UpdateCoreMenuDto, pacInfo: PacInfoType) {
private async updateMenuData(id, updateCoreMenuDto: UpdateCoreMenuDto, guardInfo: GuardInfo) {
return this.mysqlService.db
.update(pacCoreMenu)
.set({
@ -307,7 +307,7 @@ export class CoreMenuService {
orderNum: updateCoreMenuDto.orderNum,
status: updateCoreMenuDto.status,
serviceKey: updateCoreMenuDto.serviceKey,
updateby: pacInfo.userId,
updateby: guardInfo.userId,
updatetime: sql`now()`,
})
.where(eq(pacCoreMenu.menuId, id));

@ -3,8 +3,8 @@ import { CoreServiceService } from './core-service.service';
import { CreateCoreServiceDto } from './dto/create-core-service.dto';
import { UpdateCoreServiceDto } from './dto/update-core-service.dto';
import { ApiOperation, ApiProduces, ApiTags } from '@nestjs/swagger';
import { PacInfo } from '@common/decorator/pac-info/pac-info.decorator';
import { PacInfoType } from '@utils/myType';
import { UserInfoDecorator } from '@common/decorator/pac-info/pac-info.decorator';
import { GuardInfo } from '@utils/myType';
import { GetCoreServiceDto } from './dto/get-core-service.dto';
@ApiTags('系统服务')
@ -18,8 +18,8 @@ export class CoreServiceController {
})
@ApiProduces('application/json')
@Post()
create(@Body() createCoreServiceDto: CreateCoreServiceDto, @PacInfo() pacInfo: PacInfoType): Promise<object> {
return this.coreServiceService.create(createCoreServiceDto, pacInfo);
create(@Body() createCoreServiceDto: CreateCoreServiceDto, @UserInfoDecorator() guardInfo: GuardInfo): Promise<object> {
return this.coreServiceService.create(createCoreServiceDto, guardInfo);
}
@ApiOperation({
@ -48,8 +48,8 @@ export class CoreServiceController {
})
@ApiProduces('application/json')
@Patch(':serviceKey')
update(@Param('serviceKey') serviceKey: string, @Body() updateCoreServiceDto: UpdateCoreServiceDto, @PacInfo() pacInfo: PacInfoType) {
return this.coreServiceService.update(serviceKey, updateCoreServiceDto, pacInfo);
update(@Param('serviceKey') serviceKey: string, @Body() updateCoreServiceDto: UpdateCoreServiceDto, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.coreServiceService.update(serviceKey, updateCoreServiceDto, guardInfo);
}
@ApiOperation({
@ -58,7 +58,7 @@ export class CoreServiceController {
})
@ApiProduces('application/json')
@Delete(':serviceKey')
remove(@Param('serviceKey') serviceKey: string, @PacInfo() pacInfo: PacInfoType) {
return this.coreServiceService.remove(serviceKey, pacInfo);
remove(@Param('serviceKey') serviceKey: string, @UserInfoDecorator() guardInfo: GuardInfo) {
return this.coreServiceService.remove(serviceKey, guardInfo);
}
}

@ -5,7 +5,7 @@ import { LoggerService } from '@service/logger/logger.service';
import { MysqlService } from '@common/service/mysql/mysql.service';
import { pacAuthUser, pacCoreService } from '@entities/schema';
import { and, asc, desc, eq, isNull, like, or, sql } from 'drizzle-orm';
import { PacInfoType } from '@utils/myType';
import { GuardInfo } from '@utils/myType';
import { GetCoreServiceDto } from '@app/core-service/dto/get-core-service.dto';
import { likeQuery } from '@utils/likeQuery';
import { RedisService } from '@common/service/redis/redis.service';
@ -27,9 +27,9 @@ export class CoreServiceService {
* DATE: 2024-05-30 21:06:24 -
* up: 2024-06-23 14:05:20 - root的新增
* */
public async create(createCoreServiceDto: CreateCoreServiceDto, pacInfo: PacInfoType) {
public async create(createCoreServiceDto: CreateCoreServiceDto, guardInfo: GuardInfo) {
// ! 判断是否是root账户
if (this.config.get<number>('masterId') !== pacInfo.userId) {
if (this.config.get<number>('masterId') !== guardInfo.userId) {
throw new HttpException('没有权限删除菜单!', HttpStatus.UNAUTHORIZED);
}
@ -48,7 +48,7 @@ export class CoreServiceService {
if (result.length > 0) throw new HttpException('服务标识重复!', HttpStatus.CONFLICT);
// ! 添加服务数据
const newPacCoreService = await this.addServiceData(createCoreServiceDto, pacInfo);
const newPacCoreService = await this.addServiceData(createCoreServiceDto, guardInfo);
// ! 解锁
lock();
@ -86,9 +86,9 @@ export class CoreServiceService {
* DATE: 2024-05-30 21:20:19 -
* up: 2024-06-23 14:17:37 - root权限限制serviceKey数据结构
* */
public async update(serviceKey: string, updateCoreServiceDto: UpdateCoreServiceDto, pacInfo: PacInfoType) {
public async update(serviceKey: string, updateCoreServiceDto: UpdateCoreServiceDto, guardInfo: GuardInfo) {
// ! 判断是否是root账户
if (this.config.get<number>('masterId') !== pacInfo.userId) {
if (this.config.get<number>('masterId') !== guardInfo.userId) {
throw new HttpException('没有权限删除菜单!', HttpStatus.UNAUTHORIZED);
}
@ -119,7 +119,7 @@ export class CoreServiceService {
// @ 核心业务
try {
// ! 更新数据
const result = await this.updateServiceItem(serviceKey, updateCoreServiceDto, pacInfo);
const result = await this.updateServiceItem(serviceKey, updateCoreServiceDto, guardInfo);
// ! 解锁
lock();
@ -141,14 +141,14 @@ export class CoreServiceService {
* DATE: 2024-05-30 21:24:33 -
* up: 2024-06-23 14:17:37 - root权限限制
* */
public async remove(serviceKey: string, pacInfo: PacInfoType) {
public async remove(serviceKey: string, guardInfo: GuardInfo) {
// ! 判断是否是root账户
if (this.config.get<number>('masterId') !== pacInfo.userId) {
if (this.config.get<number>('masterId') !== guardInfo.userId) {
throw new HttpException('没有权限删除菜单!', HttpStatus.UNAUTHORIZED);
}
// ! 执行删除并返回
return await this.deleteServiceItem(serviceKey, pacInfo);
return await this.deleteServiceItem(serviceKey, guardInfo);
}
// DB 根据serviceKey查找服务数据 可用于查重
@ -157,9 +157,9 @@ export class CoreServiceService {
}
// DB 添加服务数据
private async addServiceData(createCoreServiceDto: CreateCoreServiceDto, pacInfo: PacInfoType) {
private async addServiceData(createCoreServiceDto: CreateCoreServiceDto, guardInfo: GuardInfo) {
const newServiceData: typeof pacCoreService.$inferInsert = {
createby: pacInfo.userId,
createby: guardInfo.userId,
createtime: sql`now()` as any,
serviceKey: createCoreServiceDto.serviceKey,
serviceName: createCoreServiceDto.serviceName,
@ -235,18 +235,18 @@ export class CoreServiceService {
}
// DB 删除服务
private async deleteServiceItem(serviceKey: string, pacInfo: PacInfoType) {
private async deleteServiceItem(serviceKey: string, guardInfo: GuardInfo) {
return await this.mysqlService.db
.update(pacCoreService)
.set({
deletetime: sql`now()`,
deleteby: pacInfo.userId,
deleteby: guardInfo.userId,
})
.where(eq(pacCoreService.serviceKey, serviceKey));
}
// DB 更新服务
private updateServiceItem(serviceKey: string, updateCoreServiceDto: UpdateCoreServiceDto, pacInfo: PacInfoType) {
private updateServiceItem(serviceKey: string, updateCoreServiceDto: UpdateCoreServiceDto, guardInfo: GuardInfo) {
return this.mysqlService.db
.update(pacCoreService)
.set({
@ -255,7 +255,7 @@ export class CoreServiceService {
serviceVersion: updateCoreServiceDto.serviceVersion,
serviceDesc: updateCoreServiceDto.serviceDesc,
updatetime: sql`now()`,
updateby: pacInfo.userId,
updateby: guardInfo.userId,
})
.where(eq(pacCoreService.serviceKey, serviceKey));
}

@ -16,11 +16,12 @@ import { LoggerService } from '@service/logger/logger.service';
import { RedisService } from '@common/service/redis/redis.service';
import { MysqlService } from '@common/service/mysql/mysql.service';
import { Snowflake } from '@service/snowflake/snowflake.service';
import { JwtService } from '@common/service/jwt/jwt.service';
@Global()
@Module({
providers: [LoggerService, RedisService, MysqlService, Snowflake],
exports: [LoggerService, RedisService, MysqlService, Snowflake],
providers: [LoggerService, RedisService, MysqlService, Snowflake, JwtService],
exports: [LoggerService, RedisService, MysqlService, Snowflake, JwtService],
imports: [],
})
export class GlobalModule {}

@ -1,15 +1,14 @@
import { createParamDecorator, ExecutionContext, SetMetadata } from '@nestjs/common';
import { PacInfoType } from '@utils/myType';
import { GuardInfo } from '@utils/myType';
// export const PacInfo = (...args: string[]) => SetMetadata('pac-info', args);
// export const UserInfoDecorator = (...args: string[]) => SetMetadata('pac-info', args);
// PacInfo
export const PacInfo = createParamDecorator((data: string, ctx: ExecutionContext) => {
const info: PacInfoType = {
username: 'pac',
userId: 0,
// UserInfoDecorator
export const UserInfoDecorator = createParamDecorator((data: string, ctx: ExecutionContext) => {
const request = ctx.switchToHttp().getRequest();
const info: GuardInfo = {
username: request.guardInfo.username,
userId: request.guardInfo.userId,
};
return info;
// const req = ctx.switchToHttp().getRequest();
});

@ -0,0 +1,82 @@
import { CanActivate, ExecutionContext, HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { Observable } from 'rxjs';
import { LoggerService } from '@service/logger/logger.service';
import { MysqlService } from '@common/service/mysql/mysql.service';
import { RedisService } from '@common/service/redis/redis.service';
import { Snowflake } from '@service/snowflake/snowflake.service';
import { ConfigService } from '@nestjs/config';
import { JwtService } from '@common/service/jwt/jwt.service';
import { KEY } from '@utils/key';
import MD5 from '@utils/MD5';
@Injectable()
export class AuthGuard implements CanActivate {
constructor(
private readonly logger: LoggerService,
private readonly mysqlService: MysqlService,
private readonly redisService: RedisService,
private readonly snowflake: Snowflake,
private readonly config: ConfigService,
private readonly jwt: JwtService,
) {}
canActivate(context: ExecutionContext): boolean | Promise<boolean> | Observable<boolean> {
const request = context.switchToHttp().getRequest();
// ! 路由白名单
const whitelist = this.config.get<string[]>('system.whitelist');
if (whitelist.some((route) => request.url.startsWith(route))) {
// ! 如果请求的路径在白名单中,允许直接访问
return true;
}
return new Promise(async (resolve, reject) => {
if (request.headers.authorization) {
let authorization = request.headers.authorization;
if (authorization.indexOf('Bearer ') === 0) {
authorization = authorization.split('Bearer ')[1];
}
// ! 获取Token
let token;
try {
token = (await this.jwt.verify(authorization)) as any;
} catch (e) {
token = undefined;
this.logger.warn('令牌解析错误', e, e.track);
}
// ? 判断Token是否过期
if (token === undefined) {
return reject(new HttpException('FORBIDDEN | 令牌过期!', HttpStatus.FORBIDDEN));
}
// ? 判断redis中是否存在
const redisTokenKey =
token.type == 'refreshToken'
? KEY.REDIS_REFRESH_TOKEN + token.userId + '-' + MD5(authorization)
: KEY.REDIS_TOKEN + token.userId + '-' + MD5(authorization);
const redisToken = await this.redisService.get(redisTokenKey);
if (redisToken == null) {
console.log('??????');
return reject(new HttpException('FORBIDDEN | 令牌过期!', HttpStatus.FORBIDDEN));
}
// ? 是否是refreshToken访问非token刷新接口
if (token.type == 'refreshToken' && request.url !== '/authUser/sign/refresh') {
return reject(new HttpException('BAD_REQUEST | 令牌使用错误!', HttpStatus.BAD_REQUEST));
}
// ? 是否是token访问token刷新接口
if (token.type == 'token' && request.url == '/authUser/sign/refresh') {
return reject(new HttpException('BAD_REQUEST | 令牌使用错误,非法续约!', HttpStatus.BAD_REQUEST));
}
// 假设token有效
resolve(true);
request.guardInfo = token;
} else {
reject(new HttpException('Unauthorized | 你没有访问权限!', HttpStatus.UNAUTHORIZED));
}
});
}
}

@ -23,6 +23,6 @@ export class JwtService {
}
public verify(token: any) {
jwt.verify(token, this.configService.get<string>('system.signin.secretKey'));
return jwt.verify(token, this.configService.get<string>('system.signin.secretKey'));
}
}

@ -68,11 +68,12 @@ export default () => ({
// 客户端在线时间 7天 ========jwt最小单位是s
refreshTokenTime: 60 * 60 * 24 * 7,
// 客户端连续在线时间 10min
tokenTime: 60 * 10,
// 客户端连续在线时间 10min 60 * 10
tokenTime: 10,
// token盐
secretKey: '326dea8337e8xsxa24f71ab960ea',
},
whitelist: ['/authUser/sign/in', '/api/login'],
},
});

@ -0,0 +1,32 @@
// | ------------------------------------------------------------
// | @版本: version 0.1
// | @创建人: 【Nie-hotok】
// | @E-mail: x71291@outlook.com
// | @所在项目: pac-auth
// | @文件描述: key.ts -
// | @创建时间: 2024-06-30 10:44
// | @更新时间: 2024-06-30 10:44
// | @修改记录:
// | -*-*-*- (时间--修改人--修改说明) -*-*-*-
// | =
// | ------------------------------------------------------------
export const KEY = {
// ! 正常请求Token的Redis前缀
REDIS_TOKEN: 'CLIENT-ONLINE-',
// ! 刷新Token的Redis前缀
REDIS_REFRESH_TOKEN: 'CLIENT-',
// ! 最大客户端登陆数量的Redis前缀
REDIS_MAX_CLIENT: 'ENV_MAX_SIGNIN_CLIENT',
// ! 客户端登陆错误的次数 Redis前缀
REDIS_FIELD_SIGNIN_NUM: 'FIELD_SIGNIN_NUM-',
// ! 系统允许的最大错误登录数量
REDIS_MAX_FIELD_SIGNIN_NUM: 'MAX_FIELD_SIGNIN_NUM',
// ! 最大登录失败后的冷却时间
REDIS_WAITING_SIGNIN_TIME: 'CONFIG_MAX_TIME_FIELD_SIGNIN',
};

@ -11,7 +11,7 @@
// | =
// | ------------------------------------------------------------
export interface PacInfoType {
export interface GuardInfo {
username: string;
userId: number;
}

Loading…
Cancel
Save