@saihu/common 1.1.27 → 1.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +211 -1
- package/dist/auth/custom-request.d.ts +3 -0
- package/dist/auth/custom-request.d.ts.map +1 -1
- package/dist/auth/decorators.d.ts +4 -0
- package/dist/auth/decorators.d.ts.map +1 -1
- package/dist/auth/decorators.js +8 -1
- package/dist/auth/guards/permission.guard.d.ts +14 -0
- package/dist/auth/guards/permission.guard.d.ts.map +1 -0
- package/dist/auth/guards/permission.guard.js +98 -0
- package/dist/auth/index.d.ts +4 -2
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +6 -0
- package/dist/consts/common.consts.d.ts +8 -0
- package/dist/consts/common.consts.d.ts.map +1 -0
- package/dist/consts/common.consts.js +10 -0
- package/dist/consts/index.d.ts +2 -0
- package/dist/consts/index.d.ts.map +1 -0
- package/dist/consts/index.js +17 -0
- package/dist/dto/index.d.ts +1 -0
- package/dist/dto/index.d.ts.map +1 -1
- package/dist/dto/index.js +1 -0
- package/dist/dto/operlog.dto.d.ts +17 -0
- package/dist/dto/operlog.dto.d.ts.map +1 -0
- package/dist/dto/operlog.dto.js +2 -0
- package/dist/index.d.ts +8 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/interceptors/index.d.ts +1 -0
- package/dist/interceptors/index.d.ts.map +1 -1
- package/dist/interceptors/index.js +1 -0
- package/dist/interceptors/operlog.interceptor.d.ts +21 -0
- package/dist/interceptors/operlog.interceptor.d.ts.map +1 -0
- package/dist/interceptors/operlog.interceptor.js +142 -0
- package/dist/interfaces/options.interface.d.ts +39 -0
- package/dist/interfaces/options.interface.d.ts.map +1 -0
- package/dist/interfaces/options.interface.js +2 -0
- package/dist/interfaces/service.interface.d.ts +11 -0
- package/dist/interfaces/service.interface.d.ts.map +1 -0
- package/dist/interfaces/service.interface.js +2 -0
- package/dist/messaging/bootstrap.d.ts +14 -0
- package/dist/messaging/bootstrap.d.ts.map +1 -0
- package/dist/messaging/bootstrap.js +28 -0
- package/dist/messaging/topology.d.ts +19 -0
- package/dist/messaging/topology.d.ts.map +1 -0
- package/dist/messaging/topology.js +27 -0
- package/dist/saihu-common.module.d.ts +8 -0
- package/dist/saihu-common.module.d.ts.map +1 -0
- package/dist/saihu-common.module.js +101 -0
- package/dist/services/rabbitmq.service.d.ts +18 -0
- package/dist/services/rabbitmq.service.d.ts.map +1 -0
- package/dist/services/rabbitmq.service.js +126 -0
- package/dist/services/redis.service.d.ts +18 -0
- package/dist/services/redis.service.d.ts.map +1 -0
- package/dist/services/redis.service.js +104 -0
- package/package.json +7 -1
package/README.md
CHANGED
|
@@ -1,8 +1,218 @@
|
|
|
1
1
|
# Common
|
|
2
2
|
|
|
3
|
-
A collection of common utilities for NestJS applications.
|
|
3
|
+
A collection of common utilities for NestJS applications, including permission guards, operation logging, and other helper utilities.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
8
|
npm install @saihu/common
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## 权限与日志记录组件
|
|
12
|
+
|
|
13
|
+
### PermissionGuard
|
|
14
|
+
|
|
15
|
+
PermissionGuard 是一个基于 NestJS 的权限守卫,用于验证用户是否有权限访问特定接口。它支持角色验证和权限验证两种方式。
|
|
16
|
+
|
|
17
|
+
#### 依赖服务
|
|
18
|
+
- redis
|
|
19
|
+
|
|
20
|
+
#### 功能特点
|
|
21
|
+
- 支持基于角色(Roles)的权限验证
|
|
22
|
+
- 支持基于权限(Perms)的细粒度权限验证
|
|
23
|
+
- 支持公共接口标记
|
|
24
|
+
- 可配置启用/禁用
|
|
25
|
+
|
|
26
|
+
#### 使用装饰器
|
|
27
|
+
|
|
28
|
+
PermissionGuard 通过以下装饰器来定义接口的权限要求:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
// 标记接口为公共接口,无需登录即可访问
|
|
32
|
+
@Public()
|
|
33
|
+
|
|
34
|
+
// 定义接口需要的角色
|
|
35
|
+
@Roles(['admin', 'editor'])
|
|
36
|
+
|
|
37
|
+
// 定义接口需要的权限
|
|
38
|
+
@Perms(['user:read', 'user:write'])
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
#### 配置选项
|
|
42
|
+
在 `CommonModuleOptions` 中可以配置 PermissionGuard 的行为:
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
interface CommonModuleOptions {
|
|
46
|
+
// 是否开启权限校验,默认为 true
|
|
47
|
+
usePerms?: boolean;
|
|
48
|
+
// 其他配置...
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
#### 使用示例
|
|
53
|
+
|
|
54
|
+
首先在模块中注册 CommonModule:
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { Module } from '@nestjs/common';
|
|
58
|
+
import { SaihuCommonModule } from '@saihu/common';
|
|
59
|
+
|
|
60
|
+
@Module({
|
|
61
|
+
imports: [
|
|
62
|
+
SaihuCommonModule.forRoot({
|
|
63
|
+
name: 'your-app-name',
|
|
64
|
+
usePerms: true, // 启用权限校验
|
|
65
|
+
// 其他配置...
|
|
66
|
+
})
|
|
67
|
+
]
|
|
68
|
+
})
|
|
69
|
+
export class AppModule {}
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
然后在控制器中使用装饰器:
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import { Controller, Get } from '@nestjs/common';
|
|
76
|
+
import { Public, Roles, Perms } from '@saihu/common';
|
|
77
|
+
|
|
78
|
+
@Controller('users')
|
|
79
|
+
@UseGuards(AuthGuard, PermissionGuard)
|
|
80
|
+
export class UserController {
|
|
81
|
+
// 公共接口,无需登录
|
|
82
|
+
@Public()
|
|
83
|
+
@Get('public')
|
|
84
|
+
getPublicData() {
|
|
85
|
+
return { message: 'This is public data' };
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// 需要 admin 或 editor 角色
|
|
89
|
+
@Roles(['admin', 'editor'])
|
|
90
|
+
@Get('admin')
|
|
91
|
+
getAdminData() {
|
|
92
|
+
return { message: 'This is admin data' };
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// 需要 user:read 权限
|
|
96
|
+
@Perms(['user:read'])
|
|
97
|
+
@Get(':id')
|
|
98
|
+
getUserById() {
|
|
99
|
+
return { message: 'User data' };
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### OperlogInterceptor
|
|
105
|
+
|
|
106
|
+
OperlogInterceptor 是一个操作日志拦截器,用于自动记录用户的操作行为,包括请求参数、响应结果、执行时间等信息。它会将日志通过 RabbitMQ 发送到消息队列。
|
|
107
|
+
|
|
108
|
+
#### 功能特点
|
|
109
|
+
- 自动记录 HTTP 请求的详细信息
|
|
110
|
+
- 支持白名单配置,可以排除特定 URL
|
|
111
|
+
- 记录用户信息、IP地址、请求参数、响应结果等
|
|
112
|
+
- 记录请求处理时间
|
|
113
|
+
- 通过 RabbitMQ 异步发送日志
|
|
114
|
+
|
|
115
|
+
#### 配置选项
|
|
116
|
+
在 `CommonModuleOptions` 中可以配置 OperlogInterceptor 的行为:
|
|
117
|
+
|
|
118
|
+
```typescript
|
|
119
|
+
interface CommonModuleOptions {
|
|
120
|
+
// 模块名称,会作为日志标题
|
|
121
|
+
name: string;
|
|
122
|
+
// 是否开启操作日志,默认为 true
|
|
123
|
+
useOperlog?: boolean;
|
|
124
|
+
// 操作日志白名单,符合条件的 URL 不会被记录
|
|
125
|
+
operlogWhitelist?: string[];
|
|
126
|
+
// RabbitMQ 配置
|
|
127
|
+
rabbitmq?: {
|
|
128
|
+
url: string;
|
|
129
|
+
};
|
|
130
|
+
// 其他配置...
|
|
131
|
+
}
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
#### 使用示例
|
|
135
|
+
|
|
136
|
+
在模块中注册 SaihuCommonModule 时配置操作日志:
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import { Module } from '@nestjs/common';
|
|
140
|
+
import { SaihuCommonModule } from '@saihu/common';
|
|
141
|
+
|
|
142
|
+
@Module({
|
|
143
|
+
imports: [
|
|
144
|
+
SaihuCommonModule.forRoot({
|
|
145
|
+
name: 'your-app-name',
|
|
146
|
+
useOperlog: true, // 启用操作日志
|
|
147
|
+
operlogWhitelist: ['/health', '/metrics'], // 排除健康检查和监控接口
|
|
148
|
+
rabbitmq: {
|
|
149
|
+
url: 'amqp://localhost:5672'
|
|
150
|
+
}
|
|
151
|
+
})
|
|
152
|
+
]
|
|
153
|
+
})
|
|
154
|
+
export class AppModule {}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
#### 日志内容
|
|
158
|
+
|
|
159
|
+
操作日志包含以下信息:
|
|
160
|
+
|
|
161
|
+
- `title`: 应用名称
|
|
162
|
+
- `method`: 控制器方法名
|
|
163
|
+
- `request_method`: HTTP 请求方法
|
|
164
|
+
- `user_agent`: 用户代理
|
|
165
|
+
- `oper_name`: 操作人员名称
|
|
166
|
+
- `dept_name`: 部门名称
|
|
167
|
+
- `oper_url`: 请求 URL
|
|
168
|
+
- `oper_ip`: 客户端 IP
|
|
169
|
+
- `oper_param`: 请求参数
|
|
170
|
+
- `json_result`: 响应结果
|
|
171
|
+
- `status`: HTTP 状态码
|
|
172
|
+
- `error_msg`: 错误信息(如有)
|
|
173
|
+
- `oper_time`: 操作时间
|
|
174
|
+
- `cost_time`: 处理耗时
|
|
175
|
+
|
|
176
|
+
## 模块配置
|
|
177
|
+
|
|
178
|
+
SaihuCommonModule 支持两种配置方式:同步配置和异步配置。
|
|
179
|
+
|
|
180
|
+
### 同步配置
|
|
181
|
+
|
|
182
|
+
```typescript
|
|
183
|
+
SaihuCommonModule.forRoot({
|
|
184
|
+
name: 'your-app-name',
|
|
185
|
+
usePerms: true,
|
|
186
|
+
useOperlog: true,
|
|
187
|
+
operlogWhitelist: ['/health'],
|
|
188
|
+
redis: {
|
|
189
|
+
url: 'redis://localhost:6379',
|
|
190
|
+
password: 'your-redis-password'
|
|
191
|
+
},
|
|
192
|
+
rabbitmq: {
|
|
193
|
+
url: 'amqp://localhost:5672'
|
|
194
|
+
}
|
|
195
|
+
})
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
### 异步配置
|
|
199
|
+
|
|
200
|
+
```typescript
|
|
201
|
+
SaihuCommonModule.forRootAsync({
|
|
202
|
+
imports: [ConfigModule],
|
|
203
|
+
useFactory: (configService: ConfigService) => ({
|
|
204
|
+
name: configService.get('APP_NAME'),
|
|
205
|
+
operlogWhitelist: configService.get('OPERLOG_WHITELIST')?.split(',') || [],
|
|
206
|
+
redis: {
|
|
207
|
+
url: configService.get('REDIS_URL'),
|
|
208
|
+
password: configService.get('REDIS_PASSWORD')
|
|
209
|
+
},
|
|
210
|
+
rabbitmq: {
|
|
211
|
+
url: configService.get('RABBITMQ_URL')
|
|
212
|
+
}
|
|
213
|
+
}),
|
|
214
|
+
inject: [ConfigService],
|
|
215
|
+
// 需要额外注册全局的APP_INTERCEPTOR
|
|
216
|
+
SaihuCommonModule.withOperlogInterceptor()
|
|
217
|
+
})
|
|
218
|
+
```
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"custom-request.d.ts","sourceRoot":"","sources":["../../src/auth/custom-request.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,IAAI;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,aAAc,SAAQ,OAAO;IAC5C,IAAI,EAAE,IAAI,CAAC;CACZ"}
|
|
1
|
+
{"version":3,"file":"custom-request.d.ts","sourceRoot":"","sources":["../../src/auth/custom-request.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,IAAI;IACnB,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,aAAc,SAAQ,OAAO;IAC5C,IAAI,EAAE,IAAI,CAAC;CACZ"}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
1
|
export declare const IS_PUBLIC_KEY = "isPublic";
|
|
2
2
|
export declare const Public: () => import("@nestjs/common").CustomDecorator<string>;
|
|
3
|
+
export declare const PERMS_KEY = "perms";
|
|
4
|
+
export declare const Perms: (perms: string[]) => import("@nestjs/common").CustomDecorator<string>;
|
|
5
|
+
export declare const ROLES_KEY = "roles";
|
|
6
|
+
export declare const Roles: (roles: string[]) => import("@nestjs/common").CustomDecorator<string>;
|
|
3
7
|
//# sourceMappingURL=decorators.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/auth/decorators.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,aAAa,CAAC;AACxC,eAAO,MAAM,MAAM,wDAAyC,CAAC"}
|
|
1
|
+
{"version":3,"file":"decorators.d.ts","sourceRoot":"","sources":["../../src/auth/decorators.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,aAAa,aAAa,CAAC;AACxC,eAAO,MAAM,MAAM,wDAAyC,CAAC;AAG7D,eAAO,MAAM,SAAS,UAAU,CAAC;AACjC,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,EAAE,qDAAkC,CAAC;AAExE,eAAO,MAAM,SAAS,UAAU,CAAC;AACjC,eAAO,MAAM,KAAK,GAAI,OAAO,MAAM,EAAE,qDAAkC,CAAC"}
|
package/dist/auth/decorators.js
CHANGED
|
@@ -1,7 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Public = exports.IS_PUBLIC_KEY = void 0;
|
|
3
|
+
exports.Roles = exports.ROLES_KEY = exports.Perms = exports.PERMS_KEY = exports.Public = exports.IS_PUBLIC_KEY = void 0;
|
|
4
4
|
const common_1 = require("@nestjs/common");
|
|
5
5
|
exports.IS_PUBLIC_KEY = 'isPublic';
|
|
6
6
|
const Public = () => (0, common_1.SetMetadata)(exports.IS_PUBLIC_KEY, true);
|
|
7
7
|
exports.Public = Public;
|
|
8
|
+
// 添加perms 和 roles 装饰器
|
|
9
|
+
exports.PERMS_KEY = 'perms';
|
|
10
|
+
const Perms = (perms) => (0, common_1.SetMetadata)(exports.PERMS_KEY, perms);
|
|
11
|
+
exports.Perms = Perms;
|
|
12
|
+
exports.ROLES_KEY = 'roles';
|
|
13
|
+
const Roles = (roles) => (0, common_1.SetMetadata)(exports.ROLES_KEY, roles);
|
|
14
|
+
exports.Roles = Roles;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { CanActivate, ExecutionContext } from "@nestjs/common";
|
|
2
|
+
import { Reflector } from "@nestjs/core";
|
|
3
|
+
import { CommonModuleOptions } from "../../interfaces/options.interface";
|
|
4
|
+
import { RedisService } from "../../interfaces/service.interface";
|
|
5
|
+
export declare class PermissionGuard implements CanActivate {
|
|
6
|
+
private readonly options;
|
|
7
|
+
private redisService;
|
|
8
|
+
private reflector;
|
|
9
|
+
private readonly logger;
|
|
10
|
+
private isEnabled;
|
|
11
|
+
constructor(options: CommonModuleOptions, redisService: RedisService, reflector: Reflector);
|
|
12
|
+
canActivate(context: ExecutionContext): Promise<boolean>;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=permission.guard.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"permission.guard.d.ts","sourceRoot":"","sources":["../../../src/auth/guards/permission.guard.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,gBAAgB,EAIjB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAQzC,OAAO,EACL,mBAAmB,EAEpB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAE,MAAM,oCAAoC,CAAC;AAElE,qBACa,eAAgB,YAAW,WAAW;IAK/C,OAAO,CAAC,QAAQ,CAAC,OAAO;IACD,OAAO,CAAC,YAAY;IAC3C,OAAO,CAAC,SAAS;IANnB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAoC;IAC3D,OAAO,CAAC,SAAS,CAAU;gBAGR,OAAO,EAAE,mBAAmB,EACd,YAAY,EAAE,YAAY,EACjD,SAAS,EAAE,SAAS;IAKxB,WAAW,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,OAAO,CAAC;CAgF/D"}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
3
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
4
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
5
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
6
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
7
|
+
};
|
|
8
|
+
var __metadata = (this && this.__metadata) || function (k, v) {
|
|
9
|
+
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
|
|
10
|
+
};
|
|
11
|
+
var __param = (this && this.__param) || function (paramIndex, decorator) {
|
|
12
|
+
return function (target, key) { decorator(target, key, paramIndex); }
|
|
13
|
+
};
|
|
14
|
+
var PermissionGuard_1;
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.PermissionGuard = void 0;
|
|
17
|
+
const common_1 = require("@nestjs/common");
|
|
18
|
+
const core_1 = require("@nestjs/core");
|
|
19
|
+
const decorators_1 = require("../decorators");
|
|
20
|
+
const dto_1 = require("../../dto");
|
|
21
|
+
const common_consts_1 = require("../../consts/common.consts");
|
|
22
|
+
let PermissionGuard = PermissionGuard_1 = class PermissionGuard {
|
|
23
|
+
constructor(options, redisService, reflector) {
|
|
24
|
+
this.options = options;
|
|
25
|
+
this.redisService = redisService;
|
|
26
|
+
this.reflector = reflector;
|
|
27
|
+
this.logger = new common_1.Logger(PermissionGuard_1.name);
|
|
28
|
+
this.isEnabled = this.options.usePerms !== false;
|
|
29
|
+
}
|
|
30
|
+
async canActivate(context) {
|
|
31
|
+
const isPublic = this.reflector.getAllAndOverride(decorators_1.IS_PUBLIC_KEY, [
|
|
32
|
+
context.getHandler(),
|
|
33
|
+
context.getClass(),
|
|
34
|
+
]);
|
|
35
|
+
// 检查是否是公共路由
|
|
36
|
+
if (isPublic) {
|
|
37
|
+
return true;
|
|
38
|
+
}
|
|
39
|
+
// 如果权限功能被禁用,允许所有请求通过
|
|
40
|
+
if (!this.isEnabled) {
|
|
41
|
+
this.logger.warn("Permission guard is disabled, allowing request");
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const requiredPermissions = this.reflector.getAllAndOverride(decorators_1.PERMS_KEY, [context.getHandler(), context.getClass()]);
|
|
46
|
+
const requiredRoles = this.reflector.getAllAndOverride(decorators_1.ROLES_KEY, [context.getHandler(), context.getClass()]);
|
|
47
|
+
const request = context.switchToHttp().getRequest();
|
|
48
|
+
const user = request.user;
|
|
49
|
+
if (!user || (!user.sub && !user.id)) {
|
|
50
|
+
throw dto_1.BaseError.unauthorized("请先登录");
|
|
51
|
+
}
|
|
52
|
+
const userId = user.id || String(user.sub);
|
|
53
|
+
const loginUser = await this.redisService.get(common_consts_1.LOGIN_USER_KEY + userId);
|
|
54
|
+
if (!loginUser) {
|
|
55
|
+
throw dto_1.BaseError.unauthorized("用户登录信息过期,请重新登录");
|
|
56
|
+
}
|
|
57
|
+
// 优先校验 roles
|
|
58
|
+
if (requiredRoles && requiredRoles.length > 0) {
|
|
59
|
+
const userRoles = (loginUser === null || loginUser === void 0 ? void 0 : loginUser.roles) || [];
|
|
60
|
+
const hasRequiredRole = requiredRoles.some((role) => userRoles.includes(role));
|
|
61
|
+
if (!hasRequiredRole) {
|
|
62
|
+
throw dto_1.BaseError.unauthorized(`权限不足。需要角色: ${requiredRoles.join(", ")}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else if (requiredPermissions && requiredPermissions.length > 0) {
|
|
66
|
+
const userPerms = (loginUser === null || loginUser === void 0 ? void 0 : loginUser.perms) || [];
|
|
67
|
+
if (!userPerms || userPerms.length === 0) {
|
|
68
|
+
throw dto_1.BaseError.unauthorized(`权限不足。需要权限: ${requiredPermissions.join(", ")}`);
|
|
69
|
+
}
|
|
70
|
+
if (userPerms.includes("*:*:*")) {
|
|
71
|
+
return true;
|
|
72
|
+
}
|
|
73
|
+
const hasAllPermissions = requiredPermissions.some((permission) => userPerms.includes(permission));
|
|
74
|
+
if (!hasAllPermissions) {
|
|
75
|
+
throw dto_1.BaseError.unauthorized(`权限不足。需要权限: ${requiredPermissions.join(", ")}`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
throw dto_1.BaseError.unauthorized(`接口未标注所需权限`);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
if (error instanceof dto_1.BaseError) {
|
|
84
|
+
throw error;
|
|
85
|
+
}
|
|
86
|
+
this.logger.error(`权限校验失败: ${error.message}`);
|
|
87
|
+
throw dto_1.BaseError.serverError(`权限校验失败: ${error.message}`);
|
|
88
|
+
}
|
|
89
|
+
return true;
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
exports.PermissionGuard = PermissionGuard;
|
|
93
|
+
exports.PermissionGuard = PermissionGuard = PermissionGuard_1 = __decorate([
|
|
94
|
+
(0, common_1.Injectable)(),
|
|
95
|
+
__param(0, (0, common_1.Inject)(common_consts_1.COMMON_MODULE_OPTIONS)),
|
|
96
|
+
__param(1, (0, common_1.Inject)(common_consts_1.REDIS_SERVICE)),
|
|
97
|
+
__metadata("design:paramtypes", [Object, Object, core_1.Reflector])
|
|
98
|
+
], PermissionGuard);
|
package/dist/auth/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
1
|
+
export * from "./auth-guard";
|
|
2
|
+
export * from "./custom-request";
|
|
3
|
+
export * from "./guards/permission.guard";
|
|
4
|
+
export { Public, Perms, Roles } from "./decorators";
|
|
3
5
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/auth/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/auth/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,kBAAkB,CAAC;AACjC,cAAc,2BAA2B,CAAC;AAC1C,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,cAAc,CAAC"}
|
package/dist/auth/index.js
CHANGED
|
@@ -14,5 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.Roles = exports.Perms = exports.Public = void 0;
|
|
17
18
|
__exportStar(require("./auth-guard"), exports);
|
|
18
19
|
__exportStar(require("./custom-request"), exports);
|
|
20
|
+
__exportStar(require("./guards/permission.guard"), exports);
|
|
21
|
+
var decorators_1 = require("./decorators");
|
|
22
|
+
Object.defineProperty(exports, "Public", { enumerable: true, get: function () { return decorators_1.Public; } });
|
|
23
|
+
Object.defineProperty(exports, "Perms", { enumerable: true, get: function () { return decorators_1.Perms; } });
|
|
24
|
+
Object.defineProperty(exports, "Roles", { enumerable: true, get: function () { return decorators_1.Roles; } });
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare const REDIS_AUTH_DB = 1;
|
|
2
|
+
export declare const LOGIN_USER_KEY = "login_user:";
|
|
3
|
+
export declare const COMMON_MODULE_OPTIONS = "COMMON_MODULE_OPTIONS";
|
|
4
|
+
export declare const REDIS_SERVICE = "REDIS_SERVICE";
|
|
5
|
+
export declare const RABBITMQ_SERVICE = "RABBITMQ_SERVICE";
|
|
6
|
+
export declare const OPER_LOG_QUEUE = "oper_log_queue";
|
|
7
|
+
export declare const OPER_LOG_EXCHANGE = "oper_log_exchange";
|
|
8
|
+
//# sourceMappingURL=common.consts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"common.consts.d.ts","sourceRoot":"","sources":["../../src/consts/common.consts.ts"],"names":[],"mappings":"AACA,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,eAAO,MAAM,cAAc,gBAAgB,CAAC;AAC5C,eAAO,MAAM,qBAAqB,0BAA0B,CAAC;AAC7D,eAAO,MAAM,aAAa,kBAAkB,CAAC;AAC7C,eAAO,MAAM,gBAAgB,qBAAqB,CAAC;AACnD,eAAO,MAAM,cAAc,mBAAmB,CAAC;AAC/C,eAAO,MAAM,iBAAiB,sBAAsB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.OPER_LOG_EXCHANGE = exports.OPER_LOG_QUEUE = exports.RABBITMQ_SERVICE = exports.REDIS_SERVICE = exports.COMMON_MODULE_OPTIONS = exports.LOGIN_USER_KEY = exports.REDIS_AUTH_DB = void 0;
|
|
4
|
+
exports.REDIS_AUTH_DB = 1;
|
|
5
|
+
exports.LOGIN_USER_KEY = 'login_user:';
|
|
6
|
+
exports.COMMON_MODULE_OPTIONS = 'COMMON_MODULE_OPTIONS';
|
|
7
|
+
exports.REDIS_SERVICE = 'REDIS_SERVICE';
|
|
8
|
+
exports.RABBITMQ_SERVICE = 'RABBITMQ_SERVICE';
|
|
9
|
+
exports.OPER_LOG_QUEUE = 'oper_log_queue';
|
|
10
|
+
exports.OPER_LOG_EXCHANGE = 'oper_log_exchange';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/consts/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./common.consts"), exports);
|
package/dist/dto/index.d.ts
CHANGED
package/dist/dto/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dto/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dto/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,cAAc,iBAAiB,CAAC;AAChC,cAAc,sBAAsB,CAAC;AACrC,cAAc,mBAAmB,CAAC;AAClC,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC"}
|
package/dist/dto/index.js
CHANGED
|
@@ -19,3 +19,4 @@ __exportStar(require("./order-service"), exports);
|
|
|
19
19
|
__exportStar(require("./basic-data-service"), exports);
|
|
20
20
|
__exportStar(require("./pricing-service"), exports);
|
|
21
21
|
__exportStar(require("./pagination.dto"), exports);
|
|
22
|
+
__exportStar(require("./operlog.dto"), exports);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export interface Operlog {
|
|
2
|
+
title: string;
|
|
3
|
+
method: string;
|
|
4
|
+
request_method: string;
|
|
5
|
+
user_agent: string;
|
|
6
|
+
oper_name: string;
|
|
7
|
+
dept_name: string;
|
|
8
|
+
oper_url: string;
|
|
9
|
+
oper_ip: string;
|
|
10
|
+
oper_param: string;
|
|
11
|
+
json_result: string;
|
|
12
|
+
status: number;
|
|
13
|
+
error_msg: string;
|
|
14
|
+
oper_time: number;
|
|
15
|
+
cost_time: number;
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=operlog.dto.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operlog.dto.d.ts","sourceRoot":"","sources":["../../src/dto/operlog.dto.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,OAAO;IAEtB,KAAK,EAAE,MAAM,CAAC;IAEd,MAAM,EAAE,MAAM,CAAC;IAEf,cAAc,EAAE,MAAM,CAAC;IAEvB,UAAU,EAAE,MAAM,CAAC;IAEnB,SAAS,EAAE,MAAM,CAAC;IAElB,SAAS,EAAE,MAAM,CAAC;IAElB,QAAQ,EAAE,MAAM,CAAC;IAEjB,OAAO,EAAE,MAAM,CAAC;IAEhB,UAAU,EAAE,MAAM,CAAC;IAEnB,WAAW,EAAE,MAAM,CAAC;IAEpB,MAAM,EAAE,MAAM,CAAC;IAEf,SAAS,EAAE,MAAM,CAAC;IAElB,SAAS,EAAE,MAAM,CAAC;IAElB,SAAS,EAAE,MAAM,CAAC;CACnB"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
export * from
|
|
2
|
-
export * from
|
|
3
|
-
export * from
|
|
4
|
-
export * from
|
|
5
|
-
export * from
|
|
6
|
-
export * from
|
|
1
|
+
export * from "./dto";
|
|
2
|
+
export * from "./consts";
|
|
3
|
+
export * from "./interceptors";
|
|
4
|
+
export * from "./filters";
|
|
5
|
+
export * from "./auth";
|
|
6
|
+
export * from "./util";
|
|
7
|
+
export * from "./logger";
|
|
8
|
+
export { SaihuCommonModule } from "./saihu-common.module";
|
|
7
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,OAAO,CAAC;AACtB,cAAc,UAAU,CAAC;AACzB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,WAAW,CAAC;AAC1B,cAAc,QAAQ,CAAC;AACvB,cAAc,QAAQ,CAAC;AACvB,cAAc,UAAU,CAAC;AACzB,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -14,9 +14,13 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.SaihuCommonModule = void 0;
|
|
17
18
|
__exportStar(require("./dto"), exports);
|
|
19
|
+
__exportStar(require("./consts"), exports);
|
|
18
20
|
__exportStar(require("./interceptors"), exports);
|
|
19
21
|
__exportStar(require("./filters"), exports);
|
|
20
22
|
__exportStar(require("./auth"), exports);
|
|
21
23
|
__exportStar(require("./util"), exports);
|
|
22
24
|
__exportStar(require("./logger"), exports);
|
|
25
|
+
var saihu_common_module_1 = require("./saihu-common.module");
|
|
26
|
+
Object.defineProperty(exports, "SaihuCommonModule", { enumerable: true, get: function () { return saihu_common_module_1.SaihuCommonModule; } });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interceptors/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interceptors/index.ts"],"names":[],"mappings":"AAAA,cAAc,yBAAyB,CAAC;AACxC,cAAc,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { NestInterceptor, ExecutionContext, CallHandler } from "@nestjs/common";
|
|
2
|
+
import { Reflector } from "@nestjs/core";
|
|
3
|
+
import { Observable } from "rxjs";
|
|
4
|
+
import { CommonModuleOptions } from "../interfaces/options.interface";
|
|
5
|
+
import { RabbitmqService } from "../interfaces/service.interface";
|
|
6
|
+
export declare class OperlogInterceptor implements NestInterceptor {
|
|
7
|
+
private reflector;
|
|
8
|
+
private readonly rabbitmqService;
|
|
9
|
+
private readonly options;
|
|
10
|
+
private readonly logger;
|
|
11
|
+
private isEnabled;
|
|
12
|
+
private whitelist;
|
|
13
|
+
constructor(reflector: Reflector, rabbitmqService: RabbitmqService, options: CommonModuleOptions);
|
|
14
|
+
intercept(context: ExecutionContext, next: CallHandler): Observable<any>;
|
|
15
|
+
private getClientIp;
|
|
16
|
+
/**
|
|
17
|
+
* 获取请求参数
|
|
18
|
+
*/
|
|
19
|
+
private getRequestParams;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=operlog.interceptor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"operlog.interceptor.d.ts","sourceRoot":"","sources":["../../src/interceptors/operlog.interceptor.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,eAAe,EACf,gBAAgB,EAChB,WAAW,EAGZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,UAAU,EAAE,MAAM,MAAM,CAAC;AAElC,OAAO,EAAE,mBAAmB,EAAE,MAAM,iCAAiC,CAAC;AAKtE,OAAO,EAAE,eAAe,EAAE,MAAM,iCAAiC,CAAC;AAIlE,qBACa,kBAAmB,YAAW,eAAe;IAMtD,OAAO,CAAC,SAAS;IACS,OAAO,CAAC,QAAQ,CAAC,eAAe;IAC3B,OAAO,CAAC,QAAQ,CAAC,OAAO;IAPzD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAuC;IAC9D,OAAO,CAAC,SAAS,CAAU;IAC3B,OAAO,CAAC,SAAS,CAAW;gBAGlB,SAAS,EAAE,SAAS,EACe,eAAe,EAAE,eAAe,EAC3B,OAAO,EAAE,mBAAmB;IAa9E,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,WAAW,GAAG,UAAU,CAAC,GAAG,CAAC;IAqExE,OAAO,CAAC,WAAW;IAiCnB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAWzB"}
|