@longzai-intelligence-auth/express 0.0.2 → 0.0.5

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 CHANGED
@@ -1,22 +1,170 @@
1
- export { mapDomainErrorToStatus } from "./core/error-mapper";
2
- export { createJwtVerifyMiddleware } from "./middlewares/jwt-verify.middleware";
3
- export type { JwtVerifyMiddlewareOptions } from "./middlewares/jwt-verify.middleware";
4
- export { createRbacMiddleware } from "./middlewares/rbac.middleware";
5
- export type { RbacMiddlewareOptions } from "./middlewares/rbac.middleware";
6
- export { createTenantMiddleware } from "./middlewares/tenant.middleware";
7
- export type { TenantMiddlewareOptions } from "./middlewares/tenant.middleware";
8
- export { createRateLimitMiddleware } from "./middlewares/rate-limit.middleware";
9
- export type { RateLimitMiddlewareOptions } from "./middlewares/rate-limit.middleware";
10
- export { createAuditMiddleware } from "./middlewares/audit.middleware";
11
- export type { AuditMiddlewareOptions } from "./middlewares/audit.middleware";
12
- export { createLoggerMiddleware } from "./middlewares/logger.middleware";
13
- export type { LoggerMiddlewareOptions } from "./middlewares/logger.middleware";
14
- export { createErrorHandlerMiddleware } from "./middlewares/error-handler.middleware";
15
- export type { ErrorHandlerMiddlewareOptions } from "./middlewares/error-handler.middleware";
16
- export { createBasicPreset } from "./presets/basic-preset";
17
- export type { BasicPresetOptions } from "./presets/basic-preset";
18
- export { createStandardPreset } from "./presets/standard-preset";
19
- export type { StandardPresetOptions } from "./presets/standard-preset";
20
- export { extractClientIp } from "./utils/extract-client-ip";
21
- export { extractUserAgent } from "./utils/extract-user-agent";
22
- export type { AuthRequest } from "./types/express-auth.types";
1
+ import { DomainError } from "@longzai-intelligence/error";
2
+ import { AccessTokenPayload, IdentityAuthBackend, LoggerService, RateLimiterPort, TokenVerifierPort } from "@longzai-intelligence-auth/core";
3
+ import { NextFunction, Request, RequestHandler, Response } from "express";
4
+
5
+ //#region src/core/error-mapper.d.ts
6
+ /** 根据 DomainError 类型映射 HTTP 状态码 */
7
+ declare function mapDomainErrorToStatus(error: DomainError): number;
8
+ //#endregion
9
+ //#region src/types/express-auth.types.d.ts
10
+ /**
11
+ * 扩展 Express Request,附加认证信息
12
+ */
13
+ interface AuthRequest extends Request {
14
+ /** 认证载荷 */
15
+ auth: AccessTokenPayload;
16
+ /** 租户 ID */
17
+ tenantId: string;
18
+ /** 客户端 IP */
19
+ clientIp?: string;
20
+ /** 限流剩余配额 */
21
+ rateLimitRemaining?: number;
22
+ }
23
+ /**
24
+ * JWT 验证中间件配置
25
+ */
26
+ type JwtVerifyMiddlewareOptions = {
27
+ /** 令牌验证器端口实例(用户注入) */verifier: TokenVerifierPort; /** 默认租户 ID */
28
+ defaultTenantId?: string;
29
+ };
30
+ /**
31
+ * RBAC 中间件配置
32
+ */
33
+ type RbacMiddlewareOptions = {
34
+ /** 令牌验证器端口实例(用户注入) */verifier: TokenVerifierPort; /** 默认租户 ID */
35
+ defaultTenantId?: string;
36
+ };
37
+ /**
38
+ * 租户中间件配置
39
+ */
40
+ type TenantMiddlewareOptions = {
41
+ /** 默认租户 ID */defaultTenantId?: string; /** 认证后端适配器 */
42
+ adapter?: IdentityAuthBackend;
43
+ };
44
+ /**
45
+ * 限流中间件配置
46
+ */
47
+ type RateLimitMiddlewareOptions = {
48
+ /** 速率限制器端口实例(用户注入) */limiter: RateLimiterPort; /** 日志服务 */
49
+ logger?: LoggerService; /** 限流键生成器 */
50
+ keyGenerator?: (req: Request) => string;
51
+ };
52
+ /**
53
+ * 日志中间件配置
54
+ */
55
+ type LoggerMiddlewareOptions = {
56
+ /** 日志服务 */logger: LoggerService;
57
+ };
58
+ /**
59
+ * 错误处理中间件配置
60
+ */
61
+ type ErrorHandlerMiddlewareOptions = {
62
+ /** 日志服务 */logger?: LoggerService;
63
+ };
64
+ /**
65
+ * 基础预设配置
66
+ */
67
+ type BasicPresetOptions = {
68
+ /** 令牌验证器端口实例(用户注入) */tokenVerifier: TokenVerifierPort; /** 默认租户 ID */
69
+ defaultTenantId?: string; /** 日志服务 */
70
+ logger?: LoggerService;
71
+ };
72
+ /**
73
+ * 标准预设配置
74
+ */
75
+ type StandardPresetOptions = {
76
+ /** 令牌验证器端口实例(用户注入) */tokenVerifier: TokenVerifierPort; /** 速率限制器端口实例(用户注入) */
77
+ rateLimiter: RateLimiterPort; /** 默认租户 ID */
78
+ defaultTenantId?: string; /** 认证后端适配器 */
79
+ adapter: IdentityAuthBackend; /** 日志服务 */
80
+ logger?: LoggerService;
81
+ };
82
+ //#endregion
83
+ //#region src/middlewares/jwt-verify.middleware.d.ts
84
+ /**
85
+ * 创建 JWT 验证中间件,从 Authorization Bearer 头提取令牌并验证
86
+ * @param options - 中间件配置选项
87
+ * @param options.verifier - 令牌验证器端口实例(用户注入)
88
+ * @param options.defaultTenantId - 默认租户 ID
89
+ * @returns Express 中间件函数
90
+ */
91
+ declare function createJwtVerifyMiddleware(options: JwtVerifyMiddlewareOptions): (req: Request, _res: Response, next: NextFunction) => Promise<void>;
92
+ //#endregion
93
+ //#region src/middlewares/rbac.middleware.d.ts
94
+ /**
95
+ * 创建 RBAC 权限检查中间件,验证请求是否拥有指定权限
96
+ * @param options - 中间件配置选项
97
+ * @param options.verifier - 令牌验证器端口实例(用户注入)
98
+ * @param options.defaultTenantId - 默认租户 ID
99
+ * @returns 返回一个函数,接收权限字符串并返回 Express 中间件
100
+ */
101
+ declare function createRbacMiddleware(options: RbacMiddlewareOptions): (permission: string) => (req: Request, _res: Response, next: NextFunction) => Promise<void>;
102
+ //#endregion
103
+ //#region src/middlewares/tenant.middleware.d.ts
104
+ /**
105
+ * 创建租户中间件,从 x-tenant-id 头提取租户 ID 并验证租户状态
106
+ */
107
+ declare function createTenantMiddleware(options?: TenantMiddlewareOptions): (req: Request, _res: Response, next: NextFunction) => Promise<void>;
108
+ //#endregion
109
+ //#region src/middlewares/rate-limit.middleware.d.ts
110
+ /**
111
+ * 默认限流键生成器,从请求中提取客户端 IP
112
+ * @param req - Express 请求对象
113
+ * @returns 客户端 IP 地址
114
+ */
115
+ declare function defaultKeyGenerator(req: Request): string;
116
+ /**
117
+ * 创建限流中间件,基于 IP + 路径进行限流
118
+ * @param options - 中间件配置选项
119
+ * @param options.limiter - 速率限制器端口实例(用户注入)
120
+ * @param options.logger - 日志服务(可选)
121
+ * @param options.keyGenerator - 限流键生成器(可选)
122
+ * @returns Express 中间件函数
123
+ */
124
+ declare function createRateLimitMiddleware(options: RateLimitMiddlewareOptions): (req: Request, _res: Response, next: NextFunction) => Promise<void>;
125
+ //#endregion
126
+ //#region src/middlewares/logger.middleware.d.ts
127
+ /**
128
+ * 创建日志中间件,记录请求、响应和错误日志
129
+ */
130
+ declare function createLoggerMiddleware(options: LoggerMiddlewareOptions): (req: Request, res: Response, next: NextFunction) => void;
131
+ //#endregion
132
+ //#region src/middlewares/error-handler.middleware.d.ts
133
+ /**
134
+ * 创建错误处理中间件,捕获 DomainError 并映射为 HTTP 状态码响应
135
+ */
136
+ declare function createErrorHandlerMiddleware(options?: ErrorHandlerMiddlewareOptions): (error: Error, req: Request, res: Response, _next: NextFunction) => void;
137
+ //#endregion
138
+ //#region src/presets/basic-preset.d.ts
139
+ /**
140
+ * 创建基础预设中间件集合,包含 JWT 验证和错误处理
141
+ * @param options - 预设配置选项
142
+ * @param options.tokenVerifier - 令牌验证器端口实例(用户注入)
143
+ * @param options.defaultTenantId - 默认租户 ID(可选)
144
+ * @param options.logger - 日志服务(可选)
145
+ * @returns Express 中间件数组
146
+ */
147
+ declare function createBasicPreset(options: BasicPresetOptions): RequestHandler[];
148
+ //#endregion
149
+ //#region src/presets/standard-preset.d.ts
150
+ /**
151
+ * 创建标准预设中间件集合,包含 JWT 验证、RBAC、租户、限流和错误处理
152
+ * @param options - 预设配置选项
153
+ * @param options.tokenVerifier - 令牌验证器端口实例(用户注入)
154
+ * @param options.rateLimiter - 速率限制器端口实例(用户注入)
155
+ * @param options.defaultTenantId - 默认租户 ID(可选)
156
+ * @param options.adapter - 认证后端适配器
157
+ * @param options.logger - 日志服务(可选)
158
+ * @returns Express 中间件数组
159
+ */
160
+ declare function createStandardPreset(options: StandardPresetOptions): RequestHandler[];
161
+ //#endregion
162
+ //#region src/utils/extract-client-ip.d.ts
163
+ /** 从请求中提取客户端 IP 地址 */
164
+ declare function extractClientIp(req: Request): string | undefined;
165
+ //#endregion
166
+ //#region src/utils/extract-user-agent.d.ts
167
+ /** 从请求中提取用户代理 */
168
+ declare function extractUserAgent(req: Request): string | undefined;
169
+ //#endregion
170
+ 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,12 +1 @@
1
- export { mapDomainErrorToStatus } from "./core/error-mapper";
2
- export { createJwtVerifyMiddleware } from "./middlewares/jwt-verify.middleware";
3
- export { createRbacMiddleware } from "./middlewares/rbac.middleware";
4
- export { createTenantMiddleware } from "./middlewares/tenant.middleware";
5
- export { createRateLimitMiddleware } from "./middlewares/rate-limit.middleware";
6
- export { createAuditMiddleware } from "./middlewares/audit.middleware";
7
- export { createLoggerMiddleware } from "./middlewares/logger.middleware";
8
- export { createErrorHandlerMiddleware } from "./middlewares/error-handler.middleware";
9
- export { createBasicPreset } from "./presets/basic-preset";
10
- export { createStandardPreset } from "./presets/standard-preset";
11
- export { extractClientIp } from "./utils/extract-client-ip";
12
- export { extractUserAgent } from "./utils/extract-user-agent";
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;return async(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)}}}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=_();return e=>async(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)}}}function y(e={}){let{defaultTenantId:t=`default`,adapter:n}=e;return async(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)}}}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;return async(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)}}}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,22 +1,15 @@
1
1
  {
2
2
  "name": "@longzai-intelligence-auth/express",
3
- "version": "0.0.2",
3
+ "version": "0.0.5",
4
4
  "license": "UNLICENSED",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
- "main": "./dist/index.cjs",
8
- "module": "./dist/index.js",
7
+ "main": "./dist/index.js",
9
8
  "types": "./dist/index.d.ts",
10
9
  "exports": {
11
10
  ".": {
12
- "import": {
13
- "types": "./dist/index.d.ts",
14
- "default": "./dist/index.js"
15
- },
16
- "require": {
17
- "types": "./dist/index.d.cts",
18
- "default": "./dist/index.cjs"
19
- }
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js"
20
13
  }
21
14
  },
22
15
  "files": [
@@ -31,12 +24,7 @@
31
24
  "directory": "packages/express"
32
25
  },
33
26
  "dependencies": {
34
- "@longzai-intelligence-auth/core": "0.0.2",
35
- "@longzai-intelligence-auth/jwt": "0.0.2",
36
- "@longzai-intelligence-auth/rate-limit": "0.0.2",
37
- "@longzai-intelligence-auth/rbac": "0.0.2",
38
- "@longzai-intelligence-auth/session": "0.0.2",
39
- "@longzai-intelligence-auth/hashing": "0.0.2",
27
+ "@longzai-intelligence-auth/core": "0.0.5",
40
28
  "@longzai-intelligence/error": "^0.0.5"
41
29
  },
42
30
  "peerDependencies": {
@@ -47,8 +35,7 @@
47
35
  "@types/express": "^5"
48
36
  },
49
37
  "scripts": {
50
- "build": "bun build src/index.ts --outdir dist --target bun",
51
- "build:declaration": "tsgo --declaration --emitDeclarationOnly --outDir dist -p tsconfig/app.json",
38
+ "build": "tsgo --build tsconfig/build.json && resolve-aliases -p tsconfig/build.json",
52
39
  "build:prod": "NODE_ENV=production tsdown",
53
40
  "prepublishOnly": "bun run build:prod",
54
41
  "typecheck": "bun run typecheck:app && bun run typecheck:node && bun run typecheck:test",
@@ -60,6 +47,8 @@
60
47
  "test": "bun test",
61
48
  "test:watch": "bun test --watch",
62
49
  "test:coverage": "bun test --coverage",
50
+ "test:unit": "bun test src/__tests__/unit/",
51
+ "test:integration": "bun test src/__tests__/integration/",
63
52
  "clean": "rm -rf dist out .cache"
64
53
  }
65
54
  }
@@ -1,2 +0,0 @@
1
- import type { DomainError } from "@longzai-intelligence/error";
2
- export declare function mapDomainErrorToStatus(error: DomainError): number;
@@ -1,27 +0,0 @@
1
- import { AuthenticationError, DuplicateEntityError, isValidationError, isEntityNotFoundError, isPermissionDeniedError, isBusinessRuleError, isConcurrencyError, } from "@longzai-intelligence/error";
2
- import { TokenExpiredError, TokenInvalidError, TokenMissingError, MfaRequiredError, InvalidCredentialsError, AccountDisabledError, RateLimitExceededError, } from "@longzai-intelligence-auth/core";
3
- export function mapDomainErrorToStatus(error) {
4
- if (isValidationError(error))
5
- return 400;
6
- if (error instanceof TokenExpiredError ||
7
- error instanceof TokenInvalidError ||
8
- error instanceof TokenMissingError ||
9
- error instanceof MfaRequiredError ||
10
- error instanceof InvalidCredentialsError ||
11
- error instanceof AccountDisabledError ||
12
- error instanceof AuthenticationError)
13
- return 401;
14
- if (isPermissionDeniedError(error))
15
- return 403;
16
- if (isEntityNotFoundError(error))
17
- return 404;
18
- if (error instanceof DuplicateEntityError)
19
- return 409;
20
- if (error instanceof RateLimitExceededError)
21
- return 429;
22
- if (isConcurrencyError(error))
23
- return 409;
24
- if (isBusinessRuleError(error))
25
- return 422;
26
- return 500;
27
- }
@@ -1,4 +0,0 @@
1
- import type { Request, Response, NextFunction } from "express";
2
- import type { AuditMiddlewareOptions } from "../types/express-auth.types";
3
- export type { AuditMiddlewareOptions };
4
- export declare function createAuditMiddleware(options: AuditMiddlewareOptions): (_req: Request, _res: Response, next: NextFunction) => void;
@@ -1,12 +0,0 @@
1
- export function createAuditMiddleware(options) {
2
- const { adapter } = options;
3
- return (_req, _res, next) => {
4
- const authReq = _req;
5
- authReq.recordAudit = (entry) => {
6
- adapter.audit.save(entry).catch((error) => {
7
- console.error("审计日志写入失败:", error);
8
- });
9
- };
10
- next();
11
- };
12
- }
@@ -1,4 +0,0 @@
1
- import type { Request, Response, NextFunction } from "express";
2
- import type { ErrorHandlerMiddlewareOptions } from "../types/express-auth.types";
3
- export type { ErrorHandlerMiddlewareOptions };
4
- export declare function createErrorHandlerMiddleware(options?: ErrorHandlerMiddlewareOptions): (error: Error, req: Request, res: Response, _next: NextFunction) => void;
@@ -1,23 +0,0 @@
1
- import { DomainError } from "@longzai-intelligence/error";
2
- import { mapDomainErrorToStatus } from "../core/error-mapper";
3
- export function createErrorHandlerMiddleware(options = {}) {
4
- const { logger } = options;
5
- return (error, req, res, _next) => {
6
- if (error instanceof DomainError) {
7
- const status = mapDomainErrorToStatus(error);
8
- res.status(status).json({
9
- code: error.code,
10
- message: error.message,
11
- ...(error.context && Object.keys(error.context).length > 0
12
- ? { details: error.context }
13
- : {}),
14
- });
15
- return;
16
- }
17
- logger?.error("未预期的错误", {
18
- error: error instanceof Error ? error.message : String(error),
19
- stack: error instanceof Error ? error.stack : undefined,
20
- });
21
- res.status(500).json({ code: "INTERNAL_ERROR", message: "服务器内部错误" });
22
- };
23
- }
@@ -1,4 +0,0 @@
1
- import type { Request, Response, NextFunction } from "express";
2
- import type { JwtVerifyMiddlewareOptions } from "../types/express-auth.types";
3
- export type { JwtVerifyMiddlewareOptions };
4
- export declare function createJwtVerifyMiddleware(options: JwtVerifyMiddlewareOptions): (req: Request, _res: Response, next: NextFunction) => Promise<void>;
@@ -1,36 +0,0 @@
1
- import { createJwtVerifier } from "@longzai-intelligence-auth/jwt";
2
- import { TokenMissingError, TokenInvalidError } from "@longzai-intelligence-auth/core";
3
- export function createJwtVerifyMiddleware(options) {
4
- const { jwt: jwtConfig, defaultTenantId = "default" } = options;
5
- let verifierPromise = null;
6
- const getVerifier = () => {
7
- if (!verifierPromise) {
8
- verifierPromise = createJwtVerifier(jwtConfig);
9
- }
10
- return verifierPromise;
11
- };
12
- return async (req, _res, next) => {
13
- try {
14
- const authReq = req;
15
- const authHeader = req.headers["authorization"];
16
- const bearer = typeof authHeader === "string" && authHeader.startsWith("Bearer ")
17
- ? authHeader.slice(7)
18
- : null;
19
- if (!bearer) {
20
- throw new TokenMissingError();
21
- }
22
- const verifier = await getVerifier();
23
- const result = await verifier.verifyAccessToken(bearer);
24
- if (!result.success || !result.payload) {
25
- throw new TokenInvalidError(result.error);
26
- }
27
- const payload = result.payload;
28
- authReq.auth = payload;
29
- authReq.tenantId = payload.tenantId ?? defaultTenantId;
30
- next();
31
- }
32
- catch (error) {
33
- next(error);
34
- }
35
- };
36
- }
@@ -1,4 +0,0 @@
1
- import type { Request, Response, NextFunction } from "express";
2
- import type { LoggerMiddlewareOptions } from "../types/express-auth.types";
3
- export type { LoggerMiddlewareOptions };
4
- export declare function createLoggerMiddleware(options: LoggerMiddlewareOptions): (req: Request, res: Response, next: NextFunction) => void;
@@ -1,17 +0,0 @@
1
- export function createLoggerMiddleware(options) {
2
- const { logger } = options;
3
- return (req, res, next) => {
4
- const startTime = Date.now();
5
- logger.info(`${req.method} ${req.originalUrl}`);
6
- res.on("finish", () => {
7
- const duration = Date.now() - startTime;
8
- logger.info(`${req.method} ${req.originalUrl} ${res.statusCode} ${duration}ms`);
9
- });
10
- res.on("error", (error) => {
11
- logger.error(`${req.method} ${req.originalUrl} 请求错误`, {
12
- error: error instanceof Error ? error.message : String(error),
13
- });
14
- });
15
- next();
16
- };
17
- }
@@ -1,4 +0,0 @@
1
- import type { Request, Response, NextFunction } from "express";
2
- import type { RateLimitMiddlewareOptions } from "../types/express-auth.types";
3
- export type { RateLimitMiddlewareOptions };
4
- export declare function createRateLimitMiddleware(options?: RateLimitMiddlewareOptions): (req: Request, _res: Response, next: NextFunction) => Promise<void>;
@@ -1,42 +0,0 @@
1
- import { createMemoryRateLimiter } from "@longzai-intelligence-auth/rate-limit";
2
- import { RateLimitExceededError } from "@longzai-intelligence-auth/core";
3
- function defaultKeyGenerator(req) {
4
- return req.headers["x-forwarded-for"]?.split(",")[0]?.trim()
5
- ?? req.headers["x-real-ip"]
6
- ?? req.ip
7
- ?? "unknown";
8
- }
9
- export function createRateLimitMiddleware(options = { windowSeconds: 60, maxRequests: 100 }) {
10
- const { logger } = options;
11
- const keyGen = options.keyGenerator ?? defaultKeyGenerator;
12
- const limiter = createMemoryRateLimiter({
13
- windowSeconds: options.windowSeconds,
14
- maxRequests: options.maxRequests,
15
- });
16
- const timer = setInterval(() => {
17
- limiter.cleanup();
18
- }, 60_000);
19
- if (typeof process !== "undefined" && typeof process.on === "function") {
20
- process.on("exit", () => clearInterval(timer));
21
- }
22
- return async (req, _res, next) => {
23
- try {
24
- const authReq = req;
25
- const clientIp = keyGen(req);
26
- authReq.clientIp = clientIp;
27
- const path = req.path;
28
- const key = `${clientIp}:${path}`;
29
- const allowed = await limiter.check(key);
30
- if (!allowed) {
31
- logger?.warn("限流触发", { clientIp, path });
32
- throw new RateLimitExceededError();
33
- }
34
- const remaining = options.maxRequests - limiter.getCount(key);
35
- authReq.rateLimitRemaining = remaining;
36
- next();
37
- }
38
- catch (error) {
39
- next(error);
40
- }
41
- };
42
- }
@@ -1,4 +0,0 @@
1
- import type { Request, Response, NextFunction } from "express";
2
- import type { RbacMiddlewareOptions } from "../types/express-auth.types";
3
- export type { RbacMiddlewareOptions };
4
- export declare function createRbacMiddleware(options: RbacMiddlewareOptions): (permission: string) => (req: Request, _res: Response, next: NextFunction) => Promise<void>;
@@ -1,49 +0,0 @@
1
- import { createRoleChecker } from "@longzai-intelligence-auth/rbac";
2
- import { createJwtVerifier } from "@longzai-intelligence-auth/jwt";
3
- import { TokenMissingError, TokenInvalidError } from "@longzai-intelligence-auth/core";
4
- export function createRbacMiddleware(options) {
5
- const { jwt: jwtConfig, defaultTenantId = "default" } = options;
6
- const roleChecker = createRoleChecker();
7
- let verifierPromise = null;
8
- const getVerifier = () => {
9
- if (!verifierPromise) {
10
- verifierPromise = createJwtVerifier(jwtConfig);
11
- }
12
- return verifierPromise;
13
- };
14
- return (permission) => {
15
- return async (req, _res, next) => {
16
- try {
17
- const authReq = req;
18
- const authHeader = req.headers["authorization"];
19
- const bearer = typeof authHeader === "string" && authHeader.startsWith("Bearer ")
20
- ? authHeader.slice(7)
21
- : null;
22
- if (!bearer) {
23
- throw new TokenMissingError();
24
- }
25
- const verifier = await getVerifier();
26
- const result = await verifier.verifyAccessToken(bearer);
27
- if (!result.success || !result.payload) {
28
- throw new TokenInvalidError(result.error);
29
- }
30
- const payload = result.payload;
31
- authReq.auth = payload;
32
- authReq.tenantId = payload.tenantId ?? defaultTenantId;
33
- const [resource, action] = permission.split(":");
34
- if (!resource || !action) {
35
- throw new Error(`无效的权限格式: ${permission},应为 resource:action`);
36
- }
37
- const hasPermission = roleChecker.hasPermission(payload, resource, action);
38
- if (!hasPermission) {
39
- const { PermissionDeniedError } = await import("@longzai-intelligence/error");
40
- throw new PermissionDeniedError(resource, action);
41
- }
42
- next();
43
- }
44
- catch (error) {
45
- next(error);
46
- }
47
- };
48
- };
49
- }
@@ -1,4 +0,0 @@
1
- import type { Request, Response, NextFunction } from "express";
2
- import type { TenantMiddlewareOptions } from "../types/express-auth.types";
3
- export type { TenantMiddlewareOptions };
4
- export declare function createTenantMiddleware(options?: TenantMiddlewareOptions): (req: Request, _res: Response, next: NextFunction) => Promise<void>;
@@ -1,22 +0,0 @@
1
- export function createTenantMiddleware(options = {}) {
2
- const { defaultTenantId = "default", adapter } = options;
3
- return async (req, _res, next) => {
4
- try {
5
- const authReq = req;
6
- const headerTenantId = req.headers["x-tenant-id"];
7
- const tenantId = headerTenantId ?? defaultTenantId;
8
- authReq.tenantId = tenantId;
9
- if (adapter && tenantId !== defaultTenantId) {
10
- const result = await adapter.tenant.validateStatus(tenantId);
11
- if (!result.valid) {
12
- const { PermissionDeniedError } = await import("@longzai-intelligence/error");
13
- throw new PermissionDeniedError("tenant", "access");
14
- }
15
- }
16
- next();
17
- }
18
- catch (error) {
19
- next(error);
20
- }
21
- };
22
- }
@@ -1,4 +0,0 @@
1
- import type { RequestHandler } from "express";
2
- import type { BasicPresetOptions } from "../types/express-auth.types";
3
- export type { BasicPresetOptions };
4
- export declare function createBasicPreset(options: BasicPresetOptions): RequestHandler[];
@@ -1,11 +0,0 @@
1
- import { createJwtVerifyMiddleware } from "../middlewares/jwt-verify.middleware";
2
- import { createErrorHandlerMiddleware } from "../middlewares/error-handler.middleware";
3
- export function createBasicPreset(options) {
4
- return [
5
- createJwtVerifyMiddleware({
6
- jwt: options.jwt,
7
- defaultTenantId: options.defaultTenantId,
8
- }),
9
- createErrorHandlerMiddleware({ logger: options.logger }),
10
- ];
11
- }
@@ -1,4 +0,0 @@
1
- import type { RequestHandler } from "express";
2
- import type { StandardPresetOptions } from "../types/express-auth.types";
3
- export type { StandardPresetOptions };
4
- export declare function createStandardPreset(options: StandardPresetOptions): RequestHandler[];
@@ -1,27 +0,0 @@
1
- import { createJwtVerifyMiddleware } from "../middlewares/jwt-verify.middleware";
2
- import { createRbacMiddleware } from "../middlewares/rbac.middleware";
3
- import { createTenantMiddleware } from "../middlewares/tenant.middleware";
4
- import { createRateLimitMiddleware } from "../middlewares/rate-limit.middleware";
5
- import { createErrorHandlerMiddleware } from "../middlewares/error-handler.middleware";
6
- export function createStandardPreset(options) {
7
- const rbacMiddleware = createRbacMiddleware({
8
- jwt: options.jwt,
9
- defaultTenantId: options.defaultTenantId,
10
- });
11
- return [
12
- createJwtVerifyMiddleware({
13
- jwt: options.jwt,
14
- defaultTenantId: options.defaultTenantId,
15
- }),
16
- rbacMiddleware("*:*"),
17
- createTenantMiddleware({
18
- defaultTenantId: options.defaultTenantId,
19
- adapter: options.adapter,
20
- }),
21
- createRateLimitMiddleware({
22
- windowSeconds: 60,
23
- maxRequests: 100,
24
- }),
25
- createErrorHandlerMiddleware({ logger: options.logger }),
26
- ];
27
- }
@@ -1,47 +0,0 @@
1
- import type { Request } from "express";
2
- import type { JwtSignerConfig } from "@longzai-intelligence-auth/jwt";
3
- import type { IdentityAuthBackend, RateLimitConfig, LoggerService, AuditLogEntry } from "@longzai-intelligence-auth/core";
4
- import type { AccessTokenPayload } from "@longzai-intelligence-auth/core";
5
- export interface AuthRequest extends Request {
6
- auth: AccessTokenPayload;
7
- tenantId: string;
8
- clientIp?: string;
9
- rateLimitRemaining?: number;
10
- recordAudit?: (entry: Omit<AuditLogEntry, never>) => void;
11
- }
12
- export type JwtVerifyMiddlewareOptions = {
13
- jwt: JwtSignerConfig;
14
- defaultTenantId?: string;
15
- };
16
- export type RbacMiddlewareOptions = {
17
- jwt: JwtSignerConfig;
18
- defaultTenantId?: string;
19
- };
20
- export type TenantMiddlewareOptions = {
21
- defaultTenantId?: string;
22
- adapter?: IdentityAuthBackend;
23
- };
24
- export type RateLimitMiddlewareOptions = RateLimitConfig & {
25
- logger?: LoggerService;
26
- keyGenerator?: (req: Request) => string;
27
- };
28
- export type AuditMiddlewareOptions = {
29
- adapter: IdentityAuthBackend;
30
- };
31
- export type LoggerMiddlewareOptions = {
32
- logger: LoggerService;
33
- };
34
- export type ErrorHandlerMiddlewareOptions = {
35
- logger?: LoggerService;
36
- };
37
- export type BasicPresetOptions = {
38
- jwt: JwtSignerConfig;
39
- defaultTenantId?: string;
40
- logger?: LoggerService;
41
- };
42
- export type StandardPresetOptions = {
43
- jwt: JwtSignerConfig;
44
- defaultTenantId?: string;
45
- adapter: IdentityAuthBackend;
46
- logger?: LoggerService;
47
- };
@@ -1 +0,0 @@
1
- export {};
@@ -1,2 +0,0 @@
1
- import type { Request } from "express";
2
- export declare function extractClientIp(req: Request): string | undefined;
@@ -1,6 +0,0 @@
1
- export function extractClientIp(req) {
2
- return req.headers["x-forwarded-for"]?.split(",")[0]?.trim()
3
- ?? req.headers["x-real-ip"]
4
- ?? req.ip
5
- ?? undefined;
6
- }
@@ -1,2 +0,0 @@
1
- import type { Request } from "express";
2
- export declare function extractUserAgent(req: Request): string | undefined;
@@ -1,3 +0,0 @@
1
- export function extractUserAgent(req) {
2
- return req.headers["user-agent"] ?? undefined;
3
- }