@longzai-intelligence-auth/express 0.0.5 → 0.0.7
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/dist/index.d.ts +127 -29
- package/dist/index.js +1 -1
- package/package.json +3 -3
package/dist/index.d.ts
CHANGED
|
@@ -3,89 +3,160 @@ import { AccessTokenPayload, IdentityAuthBackend, LoggerService, RateLimiterPort
|
|
|
3
3
|
import { NextFunction, Request, RequestHandler, Response } from "express";
|
|
4
4
|
|
|
5
5
|
//#region src/core/error-mapper.d.ts
|
|
6
|
-
/**
|
|
6
|
+
/**
|
|
7
|
+
* 根据 DomainError 类型映射 HTTP 状态码
|
|
8
|
+
*
|
|
9
|
+
* @param error - 需要映射的领域错误实例
|
|
10
|
+
*
|
|
11
|
+
* @returns 对应的 HTTP 状态码
|
|
12
|
+
*/
|
|
7
13
|
declare function mapDomainErrorToStatus(error: DomainError): number;
|
|
8
14
|
//#endregion
|
|
9
15
|
//#region src/types/express-auth.types.d.ts
|
|
10
16
|
/**
|
|
11
17
|
* 扩展 Express Request,附加认证信息
|
|
12
18
|
*/
|
|
13
|
-
|
|
14
|
-
/**
|
|
19
|
+
type AuthRequest = {
|
|
20
|
+
/**
|
|
21
|
+
* 认证载荷
|
|
22
|
+
*/
|
|
15
23
|
auth: AccessTokenPayload;
|
|
16
|
-
/**
|
|
24
|
+
/**
|
|
25
|
+
* 租户 ID
|
|
26
|
+
*/
|
|
17
27
|
tenantId: string;
|
|
18
|
-
/**
|
|
28
|
+
/**
|
|
29
|
+
* 客户端 IP
|
|
30
|
+
*/
|
|
19
31
|
clientIp?: string;
|
|
20
|
-
/**
|
|
32
|
+
/**
|
|
33
|
+
* 限流剩余配额
|
|
34
|
+
*/
|
|
21
35
|
rateLimitRemaining?: number;
|
|
22
|
-
}
|
|
36
|
+
} & Request;
|
|
23
37
|
/**
|
|
24
38
|
* JWT 验证中间件配置
|
|
25
39
|
*/
|
|
26
40
|
type JwtVerifyMiddlewareOptions = {
|
|
27
|
-
/**
|
|
41
|
+
/**
|
|
42
|
+
* 令牌验证器端口实例(用户注入)
|
|
43
|
+
*/
|
|
44
|
+
verifier: TokenVerifierPort;
|
|
45
|
+
/**
|
|
46
|
+
* 默认租户 ID
|
|
47
|
+
*/
|
|
28
48
|
defaultTenantId?: string;
|
|
29
49
|
};
|
|
30
50
|
/**
|
|
31
51
|
* RBAC 中间件配置
|
|
32
52
|
*/
|
|
33
53
|
type RbacMiddlewareOptions = {
|
|
34
|
-
/**
|
|
54
|
+
/**
|
|
55
|
+
* 令牌验证器端口实例(用户注入)
|
|
56
|
+
*/
|
|
57
|
+
verifier: TokenVerifierPort;
|
|
58
|
+
/**
|
|
59
|
+
* 默认租户 ID
|
|
60
|
+
*/
|
|
35
61
|
defaultTenantId?: string;
|
|
36
62
|
};
|
|
37
63
|
/**
|
|
38
64
|
* 租户中间件配置
|
|
39
65
|
*/
|
|
40
66
|
type TenantMiddlewareOptions = {
|
|
41
|
-
/**
|
|
67
|
+
/**
|
|
68
|
+
* 默认租户 ID
|
|
69
|
+
*/
|
|
70
|
+
defaultTenantId?: string;
|
|
71
|
+
/**
|
|
72
|
+
* 认证后端适配器
|
|
73
|
+
*/
|
|
42
74
|
adapter?: IdentityAuthBackend;
|
|
43
75
|
};
|
|
44
76
|
/**
|
|
45
77
|
* 限流中间件配置
|
|
46
78
|
*/
|
|
47
79
|
type RateLimitMiddlewareOptions = {
|
|
48
|
-
/**
|
|
49
|
-
|
|
80
|
+
/**
|
|
81
|
+
* 速率限制器端口实例(用户注入)
|
|
82
|
+
*/
|
|
83
|
+
limiter: RateLimiterPort;
|
|
84
|
+
/**
|
|
85
|
+
* 日志服务
|
|
86
|
+
*/
|
|
87
|
+
logger?: LoggerService;
|
|
88
|
+
/**
|
|
89
|
+
* 限流键生成器
|
|
90
|
+
*/
|
|
50
91
|
keyGenerator?: (req: Request) => string;
|
|
51
92
|
};
|
|
52
93
|
/**
|
|
53
94
|
* 日志中间件配置
|
|
54
95
|
*/
|
|
55
96
|
type LoggerMiddlewareOptions = {
|
|
56
|
-
/**
|
|
97
|
+
/**
|
|
98
|
+
* 日志服务
|
|
99
|
+
*/
|
|
100
|
+
logger: LoggerService;
|
|
57
101
|
};
|
|
58
102
|
/**
|
|
59
103
|
* 错误处理中间件配置
|
|
60
104
|
*/
|
|
61
105
|
type ErrorHandlerMiddlewareOptions = {
|
|
62
|
-
/**
|
|
106
|
+
/**
|
|
107
|
+
* 日志服务
|
|
108
|
+
*/
|
|
109
|
+
logger?: LoggerService;
|
|
63
110
|
};
|
|
64
111
|
/**
|
|
65
112
|
* 基础预设配置
|
|
66
113
|
*/
|
|
67
114
|
type BasicPresetOptions = {
|
|
68
|
-
/**
|
|
69
|
-
|
|
115
|
+
/**
|
|
116
|
+
* 令牌验证器端口实例(用户注入)
|
|
117
|
+
*/
|
|
118
|
+
tokenVerifier: TokenVerifierPort;
|
|
119
|
+
/**
|
|
120
|
+
* 默认租户 ID
|
|
121
|
+
*/
|
|
122
|
+
defaultTenantId?: string;
|
|
123
|
+
/**
|
|
124
|
+
* 日志服务
|
|
125
|
+
*/
|
|
70
126
|
logger?: LoggerService;
|
|
71
127
|
};
|
|
72
128
|
/**
|
|
73
129
|
* 标准预设配置
|
|
74
130
|
*/
|
|
75
131
|
type StandardPresetOptions = {
|
|
76
|
-
/**
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
132
|
+
/**
|
|
133
|
+
* 令牌验证器端口实例(用户注入)
|
|
134
|
+
*/
|
|
135
|
+
tokenVerifier: TokenVerifierPort;
|
|
136
|
+
/**
|
|
137
|
+
* 速率限制器端口实例(用户注入)
|
|
138
|
+
*/
|
|
139
|
+
rateLimiter: RateLimiterPort;
|
|
140
|
+
/**
|
|
141
|
+
* 默认租户 ID
|
|
142
|
+
*/
|
|
143
|
+
defaultTenantId?: string;
|
|
144
|
+
/**
|
|
145
|
+
* 认证后端适配器
|
|
146
|
+
*/
|
|
147
|
+
adapter: IdentityAuthBackend;
|
|
148
|
+
/**
|
|
149
|
+
* 日志服务
|
|
150
|
+
*/
|
|
80
151
|
logger?: LoggerService;
|
|
81
152
|
};
|
|
82
153
|
//#endregion
|
|
83
154
|
//#region src/middlewares/jwt-verify.middleware.d.ts
|
|
84
155
|
/**
|
|
85
156
|
* 创建 JWT 验证中间件,从 Authorization Bearer 头提取令牌并验证
|
|
157
|
+
*
|
|
86
158
|
* @param options - 中间件配置选项
|
|
87
|
-
*
|
|
88
|
-
* @param options.defaultTenantId - 默认租户 ID
|
|
159
|
+
*
|
|
89
160
|
* @returns Express 中间件函数
|
|
90
161
|
*/
|
|
91
162
|
declare function createJwtVerifyMiddleware(options: JwtVerifyMiddlewareOptions): (req: Request, _res: Response, next: NextFunction) => Promise<void>;
|
|
@@ -93,9 +164,9 @@ declare function createJwtVerifyMiddleware(options: JwtVerifyMiddlewareOptions):
|
|
|
93
164
|
//#region src/middlewares/rbac.middleware.d.ts
|
|
94
165
|
/**
|
|
95
166
|
* 创建 RBAC 权限检查中间件,验证请求是否拥有指定权限
|
|
167
|
+
*
|
|
96
168
|
* @param options - 中间件配置选项
|
|
97
|
-
*
|
|
98
|
-
* @param options.defaultTenantId - 默认租户 ID
|
|
169
|
+
*
|
|
99
170
|
* @returns 返回一个函数,接收权限字符串并返回 Express 中间件
|
|
100
171
|
*/
|
|
101
172
|
declare function createRbacMiddleware(options: RbacMiddlewareOptions): (permission: string) => (req: Request, _res: Response, next: NextFunction) => Promise<void>;
|
|
@@ -103,22 +174,27 @@ declare function createRbacMiddleware(options: RbacMiddlewareOptions): (permissi
|
|
|
103
174
|
//#region src/middlewares/tenant.middleware.d.ts
|
|
104
175
|
/**
|
|
105
176
|
* 创建租户中间件,从 x-tenant-id 头提取租户 ID 并验证租户状态
|
|
177
|
+
*
|
|
178
|
+
* @param options - 中间件配置选项
|
|
179
|
+
*
|
|
180
|
+
* @returns Express 中间件函数
|
|
106
181
|
*/
|
|
107
182
|
declare function createTenantMiddleware(options?: TenantMiddlewareOptions): (req: Request, _res: Response, next: NextFunction) => Promise<void>;
|
|
108
183
|
//#endregion
|
|
109
184
|
//#region src/middlewares/rate-limit.middleware.d.ts
|
|
110
185
|
/**
|
|
111
186
|
* 默认限流键生成器,从请求中提取客户端 IP
|
|
187
|
+
*
|
|
112
188
|
* @param req - Express 请求对象
|
|
189
|
+
*
|
|
113
190
|
* @returns 客户端 IP 地址
|
|
114
191
|
*/
|
|
115
192
|
declare function defaultKeyGenerator(req: Request): string;
|
|
116
193
|
/**
|
|
117
194
|
* 创建限流中间件,基于 IP + 路径进行限流
|
|
195
|
+
*
|
|
118
196
|
* @param options - 中间件配置选项
|
|
119
|
-
*
|
|
120
|
-
* @param options.logger - 日志服务(可选)
|
|
121
|
-
* @param options.keyGenerator - 限流键生成器(可选)
|
|
197
|
+
*
|
|
122
198
|
* @returns Express 中间件函数
|
|
123
199
|
*/
|
|
124
200
|
declare function createRateLimitMiddleware(options: RateLimitMiddlewareOptions): (req: Request, _res: Response, next: NextFunction) => Promise<void>;
|
|
@@ -126,18 +202,27 @@ declare function createRateLimitMiddleware(options: RateLimitMiddlewareOptions):
|
|
|
126
202
|
//#region src/middlewares/logger.middleware.d.ts
|
|
127
203
|
/**
|
|
128
204
|
* 创建日志中间件,记录请求、响应和错误日志
|
|
205
|
+
*
|
|
206
|
+
* @param options - 中间件配置选项
|
|
207
|
+
*
|
|
208
|
+
* @returns Express 中间件函数
|
|
129
209
|
*/
|
|
130
210
|
declare function createLoggerMiddleware(options: LoggerMiddlewareOptions): (req: Request, res: Response, next: NextFunction) => void;
|
|
131
211
|
//#endregion
|
|
132
212
|
//#region src/middlewares/error-handler.middleware.d.ts
|
|
133
213
|
/**
|
|
134
214
|
* 创建错误处理中间件,捕获 DomainError 并映射为 HTTP 状态码响应
|
|
215
|
+
*
|
|
216
|
+
* @param options - 中间件配置选项
|
|
217
|
+
*
|
|
218
|
+
* @returns Express 错误处理中间件函数
|
|
135
219
|
*/
|
|
136
220
|
declare function createErrorHandlerMiddleware(options?: ErrorHandlerMiddlewareOptions): (error: Error, req: Request, res: Response, _next: NextFunction) => void;
|
|
137
221
|
//#endregion
|
|
138
222
|
//#region src/presets/basic-preset.d.ts
|
|
139
223
|
/**
|
|
140
224
|
* 创建基础预设中间件集合,包含 JWT 验证和错误处理
|
|
225
|
+
*
|
|
141
226
|
* @param options - 预设配置选项
|
|
142
227
|
* @param options.tokenVerifier - 令牌验证器端口实例(用户注入)
|
|
143
228
|
* @param options.defaultTenantId - 默认租户 ID(可选)
|
|
@@ -149,6 +234,7 @@ declare function createBasicPreset(options: BasicPresetOptions): RequestHandler[
|
|
|
149
234
|
//#region src/presets/standard-preset.d.ts
|
|
150
235
|
/**
|
|
151
236
|
* 创建标准预设中间件集合,包含 JWT 验证、RBAC、租户、限流和错误处理
|
|
237
|
+
*
|
|
152
238
|
* @param options - 预设配置选项
|
|
153
239
|
* @param options.tokenVerifier - 令牌验证器端口实例(用户注入)
|
|
154
240
|
* @param options.rateLimiter - 速率限制器端口实例(用户注入)
|
|
@@ -160,11 +246,23 @@ declare function createBasicPreset(options: BasicPresetOptions): RequestHandler[
|
|
|
160
246
|
declare function createStandardPreset(options: StandardPresetOptions): RequestHandler[];
|
|
161
247
|
//#endregion
|
|
162
248
|
//#region src/utils/extract-client-ip.d.ts
|
|
163
|
-
/**
|
|
249
|
+
/**
|
|
250
|
+
* 从请求中提取客户端 IP 地址
|
|
251
|
+
*
|
|
252
|
+
* @param req - Express 请求对象
|
|
253
|
+
*
|
|
254
|
+
* @returns 客户端 IP 地址,如果无法提取则返回 undefined
|
|
255
|
+
*/
|
|
164
256
|
declare function extractClientIp(req: Request): string | undefined;
|
|
165
257
|
//#endregion
|
|
166
258
|
//#region src/utils/extract-user-agent.d.ts
|
|
167
|
-
/**
|
|
259
|
+
/**
|
|
260
|
+
* 从请求中提取用户代理
|
|
261
|
+
*
|
|
262
|
+
* @param req - Express 请求对象
|
|
263
|
+
*
|
|
264
|
+
* @returns 用户代理字符串,如果不存在则返回 undefined
|
|
265
|
+
*/
|
|
168
266
|
declare function extractUserAgent(req: Request): string | undefined;
|
|
169
267
|
//#endregion
|
|
170
268
|
export { type AuthRequest, type BasicPresetOptions, type ErrorHandlerMiddlewareOptions, type JwtVerifyMiddlewareOptions, type LoggerMiddlewareOptions, type RateLimitMiddlewareOptions, type RbacMiddlewareOptions, type StandardPresetOptions, type TenantMiddlewareOptions, createBasicPreset, createErrorHandlerMiddleware, createJwtVerifyMiddleware, createLoggerMiddleware, createRateLimitMiddleware, createRbacMiddleware, createStandardPreset, createTenantMiddleware, defaultKeyGenerator, extractClientIp, extractUserAgent, mapDomainErrorToStatus };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{AuthenticationError as e,DomainError as t,DuplicateEntityError as n,isBusinessRuleError as r,isConcurrencyError as i,isEntityNotFoundError as a,isPermissionDeniedError as o,isValidationError as s}from"@longzai-intelligence/error";import{AccountDisabledError as c,InvalidCredentialsError as l,MfaRequiredError as u,RateLimitExceededError as d,TokenExpiredError as f,TokenInvalidError as p,TokenMissingError as m}from"@longzai-intelligence-auth/core";function h(t){return s(t)?400:t instanceof f||t instanceof p||t instanceof m||t instanceof u||t instanceof l||t instanceof c||t instanceof e?401:o(t)?403:a(t)?404:t instanceof n?409:t instanceof d?429:i(t)?409:r(t)?422:500}function g(e){let{verifier:t,defaultTenantId:n=`default`}=e;
|
|
1
|
+
import{AuthenticationError as e,DomainError as t,DuplicateEntityError as n,isBusinessRuleError as r,isConcurrencyError as i,isEntityNotFoundError as a,isPermissionDeniedError as o,isValidationError as s}from"@longzai-intelligence/error";import{AccountDisabledError as c,InvalidCredentialsError as l,MfaRequiredError as u,RateLimitExceededError as d,TokenExpiredError as f,TokenInvalidError as p,TokenMissingError as m}from"@longzai-intelligence-auth/core";function h(t){return s(t)?400:t instanceof f||t instanceof p||t instanceof m||t instanceof u||t instanceof l||t instanceof c||t instanceof e?401:o(t)?403:a(t)?404:t instanceof n?409:t instanceof d?429:i(t)?409:r(t)?422:500}function g(e){let{verifier:t,defaultTenantId:n=`default`}=e;async function r(e,r,i){try{let r=e,a=e.headers.authorization,o=typeof a==`string`&&a.startsWith(`Bearer `)?a.slice(7):null;if(!o)throw new m;let s=await t.verifyAccessToken(o);if(!s.success||!s.payload)throw new p(s.error);let c=s.payload;r.auth=c,r.tenantId=c.tenantId??n,i()}catch(e){i(e)}}return r}function _(){return{extractRolesFromPayload(e){return{userId:e.sub,tenantId:e.tenantId,roles:e.roles??[]}},hasRole(e,t){return(e.roles??[]).includes(t)},hasAnyRole(e,t){let n=e.roles??[];return t.some(e=>n.includes(e))},hasPermission(e,t,n){let r=e.permissions??[],i=`${t}:${n}`;return!!(r.includes(i)||r.includes(`${t}:*`)||r.includes(`*:${n}`)||r.includes(`*:*`))},hasAnyPermission(e,t){let n=e.permissions??[];return t.some(e=>{let t=`${e.resource}:${e.action}`;return!!(n.includes(t)||n.includes(`${e.resource}:*`)||n.includes(`*:${e.action}`)||n.includes(`*:*`))})}}}function v(e){let{verifier:t,defaultTenantId:n=`default`}=e,r=_();function i(e){async function i(i,a,o){try{let a=i,s=i.headers.authorization,c=typeof s==`string`&&s.startsWith(`Bearer `)?s.slice(7):null;if(!c)throw new m;let l=await t.verifyAccessToken(c);if(!l.success||!l.payload)throw new p(l.error);let u=l.payload;a.auth=u,a.tenantId=u.tenantId??n;let[d,f]=e.split(`:`);if(!d||!f)throw Error(`无效的权限格式: ${e},应为 resource:action`);if(!r.hasPermission(u,d,f)){let{PermissionDeniedError:e}=await import(`@longzai-intelligence/error`);throw new e(d,f)}o()}catch(e){o(e)}}return i}return i}function y(e={}){let{defaultTenantId:t=`default`,adapter:n}=e;async function r(e,r,i){try{let r=e,a=e.headers[`x-tenant-id`]??t;if(r.tenantId=a,n&&a!==t&&!(await n.tenant.validateStatus(a)).valid){let{PermissionDeniedError:e}=await import(`@longzai-intelligence/error`);throw new e(`tenant`,`access`)}i()}catch(e){i(e)}}return r}function b(e){return e.headers[`x-forwarded-for`]?.split(`,`)[0]?.trim()??e.headers[`x-real-ip`]??e.ip??`unknown`}function x(e){let{limiter:t,logger:n}=e,r=e.keyGenerator??b;async function i(e,i,a){try{let i=e,o=r(e);i.clientIp=o;let s=e.path,c=`${o}:${s}`,l=await t.checkLimit(c);if(!l.allowed)throw n?.warn(`限流触发`,{clientIp:o,path:s}),new d;i.rateLimitRemaining=l.remaining,a()}catch(e){a(e)}}return i}function S(e){let{logger:t}=e;return(e,n,r)=>{let i=Date.now();t.info(`${e.method} ${e.originalUrl}`),n.on(`finish`,()=>{let r=Date.now()-i;t.info(`${e.method} ${e.originalUrl} ${n.statusCode} ${r}ms`)}),n.on(`error`,n=>{t.error(`${e.method} ${e.originalUrl} 请求错误`,{error:n instanceof Error?n.message:String(n)})}),r()}}function C(e={}){let{logger:n}=e;return(e,r,i,a)=>{if(e instanceof t){let t=h(e);i.status(t).json({code:e.code,message:e.message,...e.context&&Object.keys(e.context).length>0?{details:e.context}:{}});return}n?.error(`未预期的错误`,{error:e instanceof Error?e.message:String(e),stack:e instanceof Error?e.stack:void 0}),i.status(500).json({code:`INTERNAL_ERROR`,message:`服务器内部错误`})}}function w(e){return[g({verifier:e.tokenVerifier,defaultTenantId:e.defaultTenantId}),C({logger:e.logger})]}function T(e){let t=v({verifier:e.tokenVerifier,defaultTenantId:e.defaultTenantId});return[g({verifier:e.tokenVerifier,defaultTenantId:e.defaultTenantId}),t(`*:*`),y({defaultTenantId:e.defaultTenantId,adapter:e.adapter}),x({limiter:e.rateLimiter,logger:e.logger}),C({logger:e.logger})]}function E(e){return e.headers[`x-forwarded-for`]?.split(`,`)[0]?.trim()??e.headers[`x-real-ip`]??e.ip??void 0}function D(e){return e.headers[`user-agent`]??void 0}export{w as createBasicPreset,C as createErrorHandlerMiddleware,g as createJwtVerifyMiddleware,S as createLoggerMiddleware,x as createRateLimitMiddleware,v as createRbacMiddleware,T as createStandardPreset,y as createTenantMiddleware,b as defaultKeyGenerator,E as extractClientIp,D as extractUserAgent,h as mapDomainErrorToStatus};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@longzai-intelligence-auth/express",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"license": "UNLICENSED",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"directory": "packages/express"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"@longzai-intelligence-auth/core": "0.0.
|
|
27
|
+
"@longzai-intelligence-auth/core": "0.0.7",
|
|
28
28
|
"@longzai-intelligence/error": "^0.0.5"
|
|
29
29
|
},
|
|
30
30
|
"peerDependencies": {
|
|
@@ -49,6 +49,6 @@
|
|
|
49
49
|
"test:coverage": "bun test --coverage",
|
|
50
50
|
"test:unit": "bun test src/__tests__/unit/",
|
|
51
51
|
"test:integration": "bun test src/__tests__/integration/",
|
|
52
|
-
"clean": "
|
|
52
|
+
"clean": "rimraf dist out .cache"
|
|
53
53
|
}
|
|
54
54
|
}
|