@xlt-token/express 1.0.0

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.
@@ -0,0 +1,163 @@
1
+ import * as express from "express";
2
+ import { ErrorRequestHandler, Request, RequestHandler, Response } from "express";
3
+ import { AuthResult, AuthResult as AuthResult$1, CookieOptions, CreateOptions, DEFAULT_XLT_TOKEN_CONFIG, DeviceInfo, HttpContext, HttpContext as HttpContext$1, JwtConfig, MemoryStore, NotLoginException, NotLoginType, NotPermissionException, NotRoleException, NotSafeException, StpInterface, StpLogic, StpPermLogic, StpUtil, TokenStrategy, UuidStrategy, XLT_STP_INTERFACE, XLT_TOKEN_CONFIG, XLT_TOKEN_HOOKS, XLT_TOKEN_STORE, XLT_TOKEN_STRATEGY, XltError, XltHooks, XltMode, XltMode as XltMode$1, XltSession, XltTokenConfig, XltTokenConfig as XltTokenConfig$1, XltTokenContext, XltTokenContext as XltTokenContext$1, XltTokenStore, createMockHttpContext, createXltToken, matchPermission, setStpLogic, setStpPermLogic } from "@xlt-token/core";
4
+
5
+ //#region src/context.d.ts
6
+ interface ExpressLikeRequest {
7
+ _xltState?: Record<string, unknown>;
8
+ }
9
+ interface ExpressLikeResponse {
10
+ setHeader(name: string, value: string): void;
11
+ cookie(name: string, value: string, options?: unknown): void;
12
+ }
13
+ /**
14
+ * 将 Express `req` / `res` 适配为 core 的 `HttpContext`。
15
+ *
16
+ * `state` 复用挂在 `req._xltState` 上的请求级共享对象,使同一请求多次调用拿到同一引用。
17
+ */
18
+ declare function createExpressContext(req: Request, res: Response): HttpContext$1;
19
+ //#endregion
20
+ //#region src/types.d.ts
21
+ interface RouteAuthMeta {
22
+ ignore?: boolean;
23
+ requireLogin?: boolean;
24
+ permissions?: {
25
+ list: string[];
26
+ mode: XltMode$1;
27
+ };
28
+ roles?: {
29
+ list: string[];
30
+ mode: XltMode$1;
31
+ };
32
+ safeBusiness?: string;
33
+ }
34
+ type AuthMatcher = string | RegExp | ((req: express.Request) => boolean);
35
+ interface RouteAuthPolicy extends RouteAuthMeta {
36
+ match: AuthMatcher | AuthMatcher[];
37
+ methods?: string[];
38
+ }
39
+ interface XltMiddlewareOptions {
40
+ /** 快捷白名单,会被转换为 { match, ignore: true } */
41
+ ignore?: AuthMatcher[];
42
+ /** 路由级鉴权策略。xltMiddleware 会在鉴权前解析这些规则。 */
43
+ policies?: RouteAuthPolicy[];
44
+ }
45
+ declare global {
46
+ namespace Express {
47
+ interface Request {
48
+ _xltState?: Record<string, unknown>;
49
+ _xltRouteMeta?: RouteAuthMeta;
50
+ stpLoginId?: string;
51
+ stpToken?: string;
52
+ }
53
+ }
54
+ } //# sourceMappingURL=types.d.ts.map
55
+ //#endregion
56
+ //#region src/middleware/xlt-middleware.d.ts
57
+ /**
58
+ * 全局登录校验中间件。
59
+ *
60
+ * 执行流程:
61
+ * 1. `createExpressContext(req, res)`
62
+ * 2. `resolveRouteAuthMeta` → 写入 `req._xltRouteMeta`
63
+ * 3. `shouldCheckLogin` 判断是否需要校验,不需要则直接放行
64
+ * 4. `runAuth`(登录 + 权限 + 角色 + safe),成功后 `syncExpressAuthState`
65
+ * 5. 任意异常通过 `next(err)` 交给 `xltErrorHandler`
66
+ */
67
+ declare function xltMiddleware(xlt: XltTokenContext$1, options?: XltMiddlewareOptions): RequestHandler;
68
+ //#endregion
69
+ //#region src/middleware/ignore-auth.d.ts
70
+ /**
71
+ * 路由级 helper:标记当前路由忽略登录校验(黑名单模式下放行)。
72
+ *
73
+ * 仅写入 `req._xltRouteMeta`,因此必须在同一条 route chain 中位于 `xltMiddleware` 之前才有效。
74
+ * 推荐主路径仍是 `xltMiddleware` 的 `ignore` / `policies` 选项。
75
+ */
76
+ declare function ignoreAuth(): RequestHandler;
77
+ //#endregion
78
+ //#region src/middleware/require-login.d.ts
79
+ /**
80
+ * 路由级 helper:标记当前路由需要登录(白名单模式下开启校验)。
81
+ *
82
+ * 仅写入 `req._xltRouteMeta`,必须位于 `xltMiddleware` 之前才生效。
83
+ */
84
+ declare function requireLogin(): RequestHandler;
85
+ //#endregion
86
+ //#region src/middleware/check-permission.d.ts
87
+ /**
88
+ * 路由级 helper:声明当前路由所需权限。
89
+ *
90
+ * 仅写入 `req._xltRouteMeta.permissions`,必须位于 `xltMiddleware` 之前才生效。
91
+ */
92
+ declare function checkPermission(permission: string | string[], mode?: XltMode$1): RequestHandler;
93
+ //#endregion
94
+ //#region src/middleware/check-role.d.ts
95
+ /**
96
+ * 路由级 helper:声明当前路由所需角色。
97
+ *
98
+ * 仅写入 `req._xltRouteMeta.roles`,必须位于 `xltMiddleware` 之前才生效。
99
+ */
100
+ declare function checkRole(role: string | string[], mode?: XltMode$1): RequestHandler;
101
+ //#endregion
102
+ //#region src/middleware/check-safe.d.ts
103
+ /**
104
+ * 路由级 helper:声明当前路由需要二级认证安全窗口。
105
+ *
106
+ * 仅写入 `req._xltRouteMeta.safeBusiness`,必须位于 `xltMiddleware` 之前才生效。
107
+ */
108
+ declare function checkSafe(business: string): RequestHandler;
109
+ //#endregion
110
+ //#region src/error/xlt-error-handler.d.ts
111
+ /**
112
+ * 四参数 Express 错误中间件,挂在路由链末尾,将 core 鉴权异常转为 401/403 JSON。
113
+ * 非 xlt-token 异常透传给下一个错误处理器。
114
+ *
115
+ * @example
116
+ * app.use(xltErrorHandler());
117
+ */
118
+ declare function xltErrorHandler(): ErrorRequestHandler;
119
+ //#endregion
120
+ //#region src/auth/run-auth.d.ts
121
+ /**
122
+ * 编排登录 + 权限 + 角色 + 二级认证校验。
123
+ *
124
+ * 与 `XltTokenGuard.canActivate` 中的权限块逻辑等价:
125
+ * `checkLogin` 失败时抛出 `NotLoginException`,权限/角色/safe 校验失败时分别抛出对应异常。
126
+ */
127
+ declare function runAuth(xlt: XltTokenContext$1, httpCtx: HttpContext$1, req: Request): Promise<AuthResult$1>;
128
+ //#endregion
129
+ //#region src/auth/should-check-login.d.ts
130
+ /**
131
+ * 是否需要对当前请求执行登录校验。
132
+ *
133
+ * 与 NestJS `XltTokenGuard.requiresLogin` 行为一致:
134
+ * - 黑名单模式(`defaultCheck === true`):除被 `ignore` 标记的路由外全部校验
135
+ * - 白名单模式(`defaultCheck === false`):仅校验被 `requireLogin` 标记的路由
136
+ *
137
+ * 路由元数据由 `resolveRouteAuthMeta` 提前写入 `req._xltRouteMeta`。
138
+ */
139
+ declare function shouldCheckLogin(req: Request, config: XltTokenConfig$1): boolean;
140
+ //#endregion
141
+ //#region src/auth/resolve-route-auth-meta.d.ts
142
+ /**
143
+ * 解析当前请求命中的路由鉴权元数据。
144
+ *
145
+ * 在 `shouldCheckLogin` 和 `runAuth` 之前调用,使用 `req.originalUrl` 作为匹配目标,
146
+ * 避免 Router 嵌套时 `req.path` 丢失挂载前缀。
147
+ *
148
+ * 当多条策略同时命中时,后声明的策略覆盖前者的简单字段,并合并权限/角色列表,
149
+ * 因此用户可先声明 `/api` 默认策略,再声明 `/api/public` 例外。
150
+ */
151
+ declare function resolveRouteAuthMeta(req: Request, options?: XltMiddlewareOptions): RouteAuthMeta;
152
+ //#endregion
153
+ //#region src/sync-state.d.ts
154
+ /**
155
+ * 将鉴权成功后写入 `ctx.state` 的登录态同步到 Express `req` 上。
156
+ *
157
+ * core 在 `_resolveLoginId` 中写入 `ctx.state.stpLoginId` / `ctx.state.stpToken`,
158
+ * 这里对应同步到 `req.stpLoginId` / `req.stpToken`(与 NestJS Guard 字段命名一致)。
159
+ */
160
+ declare function syncExpressAuthState(req: Request, ctx: HttpContext$1): void;
161
+ //#endregion
162
+ export { type AuthMatcher, type AuthResult, type CookieOptions, type CreateOptions, DEFAULT_XLT_TOKEN_CONFIG, type DeviceInfo, type ExpressLikeRequest, type ExpressLikeResponse, type HttpContext, type JwtConfig, MemoryStore, NotLoginException, NotLoginType, NotPermissionException, NotRoleException, NotSafeException, type RouteAuthMeta, type RouteAuthPolicy, type StpInterface, StpLogic, StpPermLogic, StpUtil, type TokenStrategy, UuidStrategy, XLT_STP_INTERFACE, XLT_TOKEN_CONFIG, XLT_TOKEN_HOOKS, XLT_TOKEN_STORE, XLT_TOKEN_STRATEGY, XltError, type XltHooks, type XltMiddlewareOptions, XltMode, XltSession, type XltTokenConfig, type XltTokenContext, type XltTokenStore, checkPermission, checkRole, checkSafe, createExpressContext, createMockHttpContext, createXltToken, ignoreAuth, matchPermission, requireLogin, resolveRouteAuthMeta, runAuth, setStpLogic, setStpPermLogic, shouldCheckLogin, syncExpressAuthState, xltErrorHandler, xltMiddleware };
163
+ //# sourceMappingURL=index.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/context.ts","../src/types.ts","../src/middleware/xlt-middleware.ts","../src/middleware/ignore-auth.ts","../src/middleware/require-login.ts","../src/middleware/check-permission.ts","../src/middleware/check-role.ts","../src/middleware/check-safe.ts","../src/error/xlt-error-handler.ts","../src/auth/run-auth.ts","../src/auth/should-check-login.ts","../src/auth/resolve-route-auth-meta.ts","../src/sync-state.ts"],"mappings":";;;;;UAGiB,kBAAA;EACf,SAAA,GAAY,MAAA;AAAA;AAAA,UAGG,mBAAA;EACf,SAAA,CAAU,IAAA,UAAc,KAAA;EACxB,MAAA,CAAO,IAAA,UAAc,KAAA,UAAe,OAAA;AAAA;;AAFtC;;;;iBAUgB,oBAAA,CAAqB,GAAA,EAAK,OAAA,EAAS,GAAA,EAAK,QAAA,GAAW,aAAA;;;UCflD,aAAA;EACf,MAAA;EACA,YAAA;EACA,WAAA;IAAgB,IAAA;IAAgB,IAAA,EAAM,SAAA;EAAA;EACtC,KAAA;IAAU,IAAA;IAAgB,IAAA,EAAM,SAAA;EAAA;EAChC,YAAA;AAAA;AAAA,KAGU,WAAA,YAER,MAAA,KACE,GAAA,EADI,OAAA,CACmB,OAAA;AAAA,UAEZ,eAAA,SAAwB,aAAA;EACvC,KAAA,EAAO,WAAA,GAAc,WAAA;EACrB,OAAA;AAAA;AAAA,UAGe,oBAAA;EDXqB;ECapC,MAAA,GAAS,WAAA;EDb4C;ECerD,QAAA,GAAW,eAAA;AAAA;AAAA,QAWL,MAAA;EAAA,UACI,OAAA;IAAA,UACE,OAAA;MACR,SAAA,GAAY,MAAA;MACZ,aAAA,GAAgB,aAAA;MAChB,UAAA;MACA,QAAA;IAAA;EAAA;AAAA;;;;ADtCN;;;;;AAIA;;;;iBEcgB,aAAA,CACd,GAAA,EAAK,iBAAA,EACL,OAAA,GAAS,oBAAA,GACR,cAAA;;;;;;;AFrBH;;iBGKgB,UAAA,CAAA,GAAc,cAAA;;;;;;;AHL9B;iBIIgB,YAAA,CAAA,GAAgB,cAAA;;;;;;AJJhC;;iBKKgB,eAAA,CACd,UAAA,qBACA,IAAA,GAAM,SAAA,GACL,cAAA;;;;;;ALRH;;iBMKgB,SAAA,CAAU,IAAA,qBAAyB,IAAA,GAAM,SAAA,GAAwB,cAAA;;;;;;;ANLjF;iBOIgB,SAAA,CAAU,QAAA,WAAmB,cAAA;;;;;;;APJ7C;;;iBQOgB,eAAA,CAAA,GAAmB,mBAAA;;;;;;ARPnC;;;iBSMsB,OAAA,CACpB,GAAA,EAAK,iBAAA,EACL,OAAA,EAAS,aAAA,EACT,GAAA,EAAK,OAAA,GACJ,OAAA,CAAQ,YAAA;;;;;;ATVX;;;;;AAIA;iBUKgB,gBAAA,CAAiB,GAAA,EAAK,OAAA,EAAS,MAAA,EAAQ,gBAAA;;;;;;AVTvD;;;;;AAIA;iBWUgB,oBAAA,CACd,GAAA,EAAK,OAAA,EACL,OAAA,GAAS,oBAAA,GACR,aAAA;;;;;;AXjBH;;;iBYMgB,oBAAA,CAAqB,GAAA,EAAK,OAAA,EAAS,GAAA,EAAK,aAAA"}
@@ -0,0 +1,163 @@
1
+ import { AuthResult, AuthResult as AuthResult$1, CookieOptions, CreateOptions, DEFAULT_XLT_TOKEN_CONFIG, DeviceInfo, HttpContext, HttpContext as HttpContext$1, JwtConfig, MemoryStore, NotLoginException, NotLoginType, NotPermissionException, NotRoleException, NotSafeException, StpInterface, StpLogic, StpPermLogic, StpUtil, TokenStrategy, UuidStrategy, XLT_STP_INTERFACE, XLT_TOKEN_CONFIG, XLT_TOKEN_HOOKS, XLT_TOKEN_STORE, XLT_TOKEN_STRATEGY, XltError, XltHooks, XltMode, XltMode as XltMode$1, XltSession, XltTokenConfig, XltTokenConfig as XltTokenConfig$1, XltTokenContext, XltTokenContext as XltTokenContext$1, XltTokenStore, createMockHttpContext, createXltToken, matchPermission, setStpLogic, setStpPermLogic } from "@xlt-token/core";
2
+ import * as express from "express";
3
+ import { ErrorRequestHandler, Request, RequestHandler, Response } from "express";
4
+
5
+ //#region src/context.d.ts
6
+ interface ExpressLikeRequest {
7
+ _xltState?: Record<string, unknown>;
8
+ }
9
+ interface ExpressLikeResponse {
10
+ setHeader(name: string, value: string): void;
11
+ cookie(name: string, value: string, options?: unknown): void;
12
+ }
13
+ /**
14
+ * 将 Express `req` / `res` 适配为 core 的 `HttpContext`。
15
+ *
16
+ * `state` 复用挂在 `req._xltState` 上的请求级共享对象,使同一请求多次调用拿到同一引用。
17
+ */
18
+ declare function createExpressContext(req: Request, res: Response): HttpContext$1;
19
+ //#endregion
20
+ //#region src/types.d.ts
21
+ interface RouteAuthMeta {
22
+ ignore?: boolean;
23
+ requireLogin?: boolean;
24
+ permissions?: {
25
+ list: string[];
26
+ mode: XltMode$1;
27
+ };
28
+ roles?: {
29
+ list: string[];
30
+ mode: XltMode$1;
31
+ };
32
+ safeBusiness?: string;
33
+ }
34
+ type AuthMatcher = string | RegExp | ((req: express.Request) => boolean);
35
+ interface RouteAuthPolicy extends RouteAuthMeta {
36
+ match: AuthMatcher | AuthMatcher[];
37
+ methods?: string[];
38
+ }
39
+ interface XltMiddlewareOptions {
40
+ /** 快捷白名单,会被转换为 { match, ignore: true } */
41
+ ignore?: AuthMatcher[];
42
+ /** 路由级鉴权策略。xltMiddleware 会在鉴权前解析这些规则。 */
43
+ policies?: RouteAuthPolicy[];
44
+ }
45
+ declare global {
46
+ namespace Express {
47
+ interface Request {
48
+ _xltState?: Record<string, unknown>;
49
+ _xltRouteMeta?: RouteAuthMeta;
50
+ stpLoginId?: string;
51
+ stpToken?: string;
52
+ }
53
+ }
54
+ } //# sourceMappingURL=types.d.ts.map
55
+ //#endregion
56
+ //#region src/middleware/xlt-middleware.d.ts
57
+ /**
58
+ * 全局登录校验中间件。
59
+ *
60
+ * 执行流程:
61
+ * 1. `createExpressContext(req, res)`
62
+ * 2. `resolveRouteAuthMeta` → 写入 `req._xltRouteMeta`
63
+ * 3. `shouldCheckLogin` 判断是否需要校验,不需要则直接放行
64
+ * 4. `runAuth`(登录 + 权限 + 角色 + safe),成功后 `syncExpressAuthState`
65
+ * 5. 任意异常通过 `next(err)` 交给 `xltErrorHandler`
66
+ */
67
+ declare function xltMiddleware(xlt: XltTokenContext$1, options?: XltMiddlewareOptions): RequestHandler;
68
+ //#endregion
69
+ //#region src/middleware/ignore-auth.d.ts
70
+ /**
71
+ * 路由级 helper:标记当前路由忽略登录校验(黑名单模式下放行)。
72
+ *
73
+ * 仅写入 `req._xltRouteMeta`,因此必须在同一条 route chain 中位于 `xltMiddleware` 之前才有效。
74
+ * 推荐主路径仍是 `xltMiddleware` 的 `ignore` / `policies` 选项。
75
+ */
76
+ declare function ignoreAuth(): RequestHandler;
77
+ //#endregion
78
+ //#region src/middleware/require-login.d.ts
79
+ /**
80
+ * 路由级 helper:标记当前路由需要登录(白名单模式下开启校验)。
81
+ *
82
+ * 仅写入 `req._xltRouteMeta`,必须位于 `xltMiddleware` 之前才生效。
83
+ */
84
+ declare function requireLogin(): RequestHandler;
85
+ //#endregion
86
+ //#region src/middleware/check-permission.d.ts
87
+ /**
88
+ * 路由级 helper:声明当前路由所需权限。
89
+ *
90
+ * 仅写入 `req._xltRouteMeta.permissions`,必须位于 `xltMiddleware` 之前才生效。
91
+ */
92
+ declare function checkPermission(permission: string | string[], mode?: XltMode$1): RequestHandler;
93
+ //#endregion
94
+ //#region src/middleware/check-role.d.ts
95
+ /**
96
+ * 路由级 helper:声明当前路由所需角色。
97
+ *
98
+ * 仅写入 `req._xltRouteMeta.roles`,必须位于 `xltMiddleware` 之前才生效。
99
+ */
100
+ declare function checkRole(role: string | string[], mode?: XltMode$1): RequestHandler;
101
+ //#endregion
102
+ //#region src/middleware/check-safe.d.ts
103
+ /**
104
+ * 路由级 helper:声明当前路由需要二级认证安全窗口。
105
+ *
106
+ * 仅写入 `req._xltRouteMeta.safeBusiness`,必须位于 `xltMiddleware` 之前才生效。
107
+ */
108
+ declare function checkSafe(business: string): RequestHandler;
109
+ //#endregion
110
+ //#region src/error/xlt-error-handler.d.ts
111
+ /**
112
+ * 四参数 Express 错误中间件,挂在路由链末尾,将 core 鉴权异常转为 401/403 JSON。
113
+ * 非 xlt-token 异常透传给下一个错误处理器。
114
+ *
115
+ * @example
116
+ * app.use(xltErrorHandler());
117
+ */
118
+ declare function xltErrorHandler(): ErrorRequestHandler;
119
+ //#endregion
120
+ //#region src/auth/run-auth.d.ts
121
+ /**
122
+ * 编排登录 + 权限 + 角色 + 二级认证校验。
123
+ *
124
+ * 与 `XltTokenGuard.canActivate` 中的权限块逻辑等价:
125
+ * `checkLogin` 失败时抛出 `NotLoginException`,权限/角色/safe 校验失败时分别抛出对应异常。
126
+ */
127
+ declare function runAuth(xlt: XltTokenContext$1, httpCtx: HttpContext$1, req: Request): Promise<AuthResult$1>;
128
+ //#endregion
129
+ //#region src/auth/should-check-login.d.ts
130
+ /**
131
+ * 是否需要对当前请求执行登录校验。
132
+ *
133
+ * 与 NestJS `XltTokenGuard.requiresLogin` 行为一致:
134
+ * - 黑名单模式(`defaultCheck === true`):除被 `ignore` 标记的路由外全部校验
135
+ * - 白名单模式(`defaultCheck === false`):仅校验被 `requireLogin` 标记的路由
136
+ *
137
+ * 路由元数据由 `resolveRouteAuthMeta` 提前写入 `req._xltRouteMeta`。
138
+ */
139
+ declare function shouldCheckLogin(req: Request, config: XltTokenConfig$1): boolean;
140
+ //#endregion
141
+ //#region src/auth/resolve-route-auth-meta.d.ts
142
+ /**
143
+ * 解析当前请求命中的路由鉴权元数据。
144
+ *
145
+ * 在 `shouldCheckLogin` 和 `runAuth` 之前调用,使用 `req.originalUrl` 作为匹配目标,
146
+ * 避免 Router 嵌套时 `req.path` 丢失挂载前缀。
147
+ *
148
+ * 当多条策略同时命中时,后声明的策略覆盖前者的简单字段,并合并权限/角色列表,
149
+ * 因此用户可先声明 `/api` 默认策略,再声明 `/api/public` 例外。
150
+ */
151
+ declare function resolveRouteAuthMeta(req: Request, options?: XltMiddlewareOptions): RouteAuthMeta;
152
+ //#endregion
153
+ //#region src/sync-state.d.ts
154
+ /**
155
+ * 将鉴权成功后写入 `ctx.state` 的登录态同步到 Express `req` 上。
156
+ *
157
+ * core 在 `_resolveLoginId` 中写入 `ctx.state.stpLoginId` / `ctx.state.stpToken`,
158
+ * 这里对应同步到 `req.stpLoginId` / `req.stpToken`(与 NestJS Guard 字段命名一致)。
159
+ */
160
+ declare function syncExpressAuthState(req: Request, ctx: HttpContext$1): void;
161
+ //#endregion
162
+ export { type AuthMatcher, type AuthResult, type CookieOptions, type CreateOptions, DEFAULT_XLT_TOKEN_CONFIG, type DeviceInfo, type ExpressLikeRequest, type ExpressLikeResponse, type HttpContext, type JwtConfig, MemoryStore, NotLoginException, NotLoginType, NotPermissionException, NotRoleException, NotSafeException, type RouteAuthMeta, type RouteAuthPolicy, type StpInterface, StpLogic, StpPermLogic, StpUtil, type TokenStrategy, UuidStrategy, XLT_STP_INTERFACE, XLT_TOKEN_CONFIG, XLT_TOKEN_HOOKS, XLT_TOKEN_STORE, XLT_TOKEN_STRATEGY, XltError, type XltHooks, type XltMiddlewareOptions, XltMode, XltSession, type XltTokenConfig, type XltTokenContext, type XltTokenStore, checkPermission, checkRole, checkSafe, createExpressContext, createMockHttpContext, createXltToken, ignoreAuth, matchPermission, requireLogin, resolveRouteAuthMeta, runAuth, setStpLogic, setStpPermLogic, shouldCheckLogin, syncExpressAuthState, xltErrorHandler, xltMiddleware };
163
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/context.ts","../src/types.ts","../src/middleware/xlt-middleware.ts","../src/middleware/ignore-auth.ts","../src/middleware/require-login.ts","../src/middleware/check-permission.ts","../src/middleware/check-role.ts","../src/middleware/check-safe.ts","../src/error/xlt-error-handler.ts","../src/auth/run-auth.ts","../src/auth/should-check-login.ts","../src/auth/resolve-route-auth-meta.ts","../src/sync-state.ts"],"mappings":";;;;;UAGiB,kBAAA;EACf,SAAA,GAAY,MAAA;AAAA;AAAA,UAGG,mBAAA;EACf,SAAA,CAAU,IAAA,UAAc,KAAA;EACxB,MAAA,CAAO,IAAA,UAAc,KAAA,UAAe,OAAA;AAAA;;AAFtC;;;;iBAUgB,oBAAA,CAAqB,GAAA,EAAK,OAAA,EAAS,GAAA,EAAK,QAAA,GAAW,aAAA;;;UCflD,aAAA;EACf,MAAA;EACA,YAAA;EACA,WAAA;IAAgB,IAAA;IAAgB,IAAA,EAAM,SAAA;EAAA;EACtC,KAAA;IAAU,IAAA;IAAgB,IAAA,EAAM,SAAA;EAAA;EAChC,YAAA;AAAA;AAAA,KAGU,WAAA,YAER,MAAA,KACE,GAAA,EADI,OAAA,CACmB,OAAA;AAAA,UAEZ,eAAA,SAAwB,aAAA;EACvC,KAAA,EAAO,WAAA,GAAc,WAAA;EACrB,OAAA;AAAA;AAAA,UAGe,oBAAA;EDXqB;ECapC,MAAA,GAAS,WAAA;EDb4C;ECerD,QAAA,GAAW,eAAA;AAAA;AAAA,QAWL,MAAA;EAAA,UACI,OAAA;IAAA,UACE,OAAA;MACR,SAAA,GAAY,MAAA;MACZ,aAAA,GAAgB,aAAA;MAChB,UAAA;MACA,QAAA;IAAA;EAAA;AAAA;;;;ADtCN;;;;;AAIA;;;;iBEcgB,aAAA,CACd,GAAA,EAAK,iBAAA,EACL,OAAA,GAAS,oBAAA,GACR,cAAA;;;;;;;AFrBH;;iBGKgB,UAAA,CAAA,GAAc,cAAA;;;;;;;AHL9B;iBIIgB,YAAA,CAAA,GAAgB,cAAA;;;;;;AJJhC;;iBKKgB,eAAA,CACd,UAAA,qBACA,IAAA,GAAM,SAAA,GACL,cAAA;;;;;;ALRH;;iBMKgB,SAAA,CAAU,IAAA,qBAAyB,IAAA,GAAM,SAAA,GAAwB,cAAA;;;;;;;ANLjF;iBOIgB,SAAA,CAAU,QAAA,WAAmB,cAAA;;;;;;;APJ7C;;;iBQOgB,eAAA,CAAA,GAAmB,mBAAA;;;;;;ARPnC;;;iBSMsB,OAAA,CACpB,GAAA,EAAK,iBAAA,EACL,OAAA,EAAS,aAAA,EACT,GAAA,EAAK,OAAA,GACJ,OAAA,CAAQ,YAAA;;;;;;ATVX;;;;;AAIA;iBUKgB,gBAAA,CAAiB,GAAA,EAAK,OAAA,EAAS,MAAA,EAAQ,gBAAA;;;;;;AVTvD;;;;;AAIA;iBWUgB,oBAAA,CACd,GAAA,EAAK,OAAA,EACL,OAAA,GAAS,oBAAA,GACR,aAAA;;;;;;AXjBH;;;iBYMgB,oBAAA,CAAqB,GAAA,EAAK,OAAA,EAAS,GAAA,EAAK,aAAA"}
package/dist/index.mjs ADDED
@@ -0,0 +1,328 @@
1
+ import { DEFAULT_XLT_TOKEN_CONFIG, MemoryStore, NotLoginException, NotLoginException as NotLoginException$1, NotLoginType, NotPermissionException, NotPermissionException as NotPermissionException$1, NotRoleException, NotRoleException as NotRoleException$1, NotSafeException, NotSafeException as NotSafeException$1, StpLogic, StpPermLogic, StpUtil, UuidStrategy, XLT_STP_INTERFACE, XLT_TOKEN_CONFIG, XLT_TOKEN_HOOKS, XLT_TOKEN_STORE, XLT_TOKEN_STRATEGY, XltError, XltMode, XltMode as XltMode$1, XltSession, createMockHttpContext, createXltToken, matchPermission, setStpLogic, setStpPermLogic } from "@xlt-token/core";
2
+
3
+ //#region src/context.ts
4
+ /**
5
+ * 将 Express `req` / `res` 适配为 core 的 `HttpContext`。
6
+ *
7
+ * `state` 复用挂在 `req._xltState` 上的请求级共享对象,使同一请求多次调用拿到同一引用。
8
+ */
9
+ function createExpressContext(req, res) {
10
+ return {
11
+ headers: { get: (name) => req.headers[name.toLowerCase()] ?? null },
12
+ cookies: { get: (name) => req.cookies?.[name] ?? null },
13
+ query: { get: (name) => req.query[name] ?? null },
14
+ state: req._xltState ??= {},
15
+ setHeader: (name, value) => {
16
+ res.setHeader(name, value);
17
+ },
18
+ setCookie: (name, value, options) => {
19
+ if (options) res.cookie(name, value, options);
20
+ else res.cookie(name, value);
21
+ },
22
+ raw: () => req
23
+ };
24
+ }
25
+
26
+ //#endregion
27
+ //#region src/auth/resolve-route-auth-meta.ts
28
+ function matchPathPrefix(path, prefix) {
29
+ const pathname = path.split("?")[0] ?? path;
30
+ return prefix === "/" || pathname === prefix || pathname.startsWith(`${prefix}/`);
31
+ }
32
+ /**
33
+ * 解析当前请求命中的路由鉴权元数据。
34
+ *
35
+ * 在 `shouldCheckLogin` 和 `runAuth` 之前调用,使用 `req.originalUrl` 作为匹配目标,
36
+ * 避免 Router 嵌套时 `req.path` 丢失挂载前缀。
37
+ *
38
+ * 当多条策略同时命中时,后声明的策略覆盖前者的简单字段,并合并权限/角色列表,
39
+ * 因此用户可先声明 `/api` 默认策略,再声明 `/api/public` 例外。
40
+ */
41
+ function resolveRouteAuthMeta(req, options = {}) {
42
+ return [...(options.ignore ?? []).map((match) => ({
43
+ match,
44
+ ignore: true
45
+ })), ...options.policies ?? []].reduce((meta, policy) => {
46
+ if (!matchPolicy(req, policy)) return meta;
47
+ const { match: _match, methods: _methods, ...nextMeta } = policy;
48
+ return mergeRouteAuthMeta(meta, nextMeta);
49
+ }, {});
50
+ }
51
+ /** 判断单条策略是否命中当前请求。 */
52
+ function matchPolicy(req, policy) {
53
+ if (policy.methods?.length) {
54
+ const method = req.method.toUpperCase();
55
+ if (!policy.methods.map((m) => m.toUpperCase()).includes(method)) return false;
56
+ }
57
+ return (Array.isArray(policy.match) ? policy.match : [policy.match]).some((matcher) => {
58
+ if (typeof matcher === "function") return matcher(req);
59
+ if (typeof matcher === "string") return matchPathPrefix(req.originalUrl, matcher);
60
+ return matcher.test(req.originalUrl);
61
+ });
62
+ }
63
+ /**
64
+ * 合并两段路由元数据:
65
+ * - `ignore` / `requireLogin` / `safeBusiness` 等简单字段:后者覆盖前者
66
+ * - `permissions` / `roles`:两者都存在时合并列表,mode 取后者
67
+ */
68
+ function mergeRouteAuthMeta(base, next) {
69
+ const merged = {
70
+ ...base,
71
+ ...next
72
+ };
73
+ if (base.permissions && next.permissions) merged.permissions = {
74
+ list: [...base.permissions.list, ...next.permissions.list],
75
+ mode: next.permissions.mode
76
+ };
77
+ if (base.roles && next.roles) merged.roles = {
78
+ list: [...base.roles.list, ...next.roles.list],
79
+ mode: next.roles.mode
80
+ };
81
+ return merged;
82
+ }
83
+
84
+ //#endregion
85
+ //#region src/auth/should-check-login.ts
86
+ /**
87
+ * 是否需要对当前请求执行登录校验。
88
+ *
89
+ * 与 NestJS `XltTokenGuard.requiresLogin` 行为一致:
90
+ * - 黑名单模式(`defaultCheck === true`):除被 `ignore` 标记的路由外全部校验
91
+ * - 白名单模式(`defaultCheck === false`):仅校验被 `requireLogin` 标记的路由
92
+ *
93
+ * 路由元数据由 `resolveRouteAuthMeta` 提前写入 `req._xltRouteMeta`。
94
+ */
95
+ function shouldCheckLogin(req, config) {
96
+ const meta = req._xltRouteMeta;
97
+ if (config.defaultCheck) return !meta?.ignore;
98
+ return meta?.requireLogin ?? false;
99
+ }
100
+
101
+ //#endregion
102
+ //#region src/auth/run-auth.ts
103
+ /**
104
+ * 编排登录 + 权限 + 角色 + 二级认证校验。
105
+ *
106
+ * 与 `XltTokenGuard.canActivate` 中的权限块逻辑等价:
107
+ * `checkLogin` 失败时抛出 `NotLoginException`,权限/角色/safe 校验失败时分别抛出对应异常。
108
+ */
109
+ async function runAuth(xlt, httpCtx, req) {
110
+ const result = await xlt.stpLogic.checkLogin(httpCtx);
111
+ const meta = req._xltRouteMeta;
112
+ if (meta?.permissions && xlt.stpPermLogic) await xlt.stpPermLogic.checkPermission(result.loginId, meta.permissions.list, meta.permissions.mode);
113
+ if (meta?.roles && xlt.stpPermLogic) await xlt.stpPermLogic.checkRole(result.loginId, meta.roles.list, meta.roles.mode);
114
+ if (meta?.safeBusiness) await xlt.stpLogic.checkSafe(result.token, meta.safeBusiness);
115
+ return result;
116
+ }
117
+
118
+ //#endregion
119
+ //#region src/sync-state.ts
120
+ /**
121
+ * 将鉴权成功后写入 `ctx.state` 的登录态同步到 Express `req` 上。
122
+ *
123
+ * core 在 `_resolveLoginId` 中写入 `ctx.state.stpLoginId` / `ctx.state.stpToken`,
124
+ * 这里对应同步到 `req.stpLoginId` / `req.stpToken`(与 NestJS Guard 字段命名一致)。
125
+ */
126
+ function syncExpressAuthState(req, ctx) {
127
+ const loginId = ctx.state.stpLoginId;
128
+ const token = ctx.state.stpToken;
129
+ if (loginId != null) req.stpLoginId = String(loginId);
130
+ if (token != null) req.stpToken = String(token);
131
+ }
132
+
133
+ //#endregion
134
+ //#region src/middleware/xlt-middleware.ts
135
+ /**
136
+ * 全局登录校验中间件。
137
+ *
138
+ * 执行流程:
139
+ * 1. `createExpressContext(req, res)`
140
+ * 2. `resolveRouteAuthMeta` → 写入 `req._xltRouteMeta`
141
+ * 3. `shouldCheckLogin` 判断是否需要校验,不需要则直接放行
142
+ * 4. `runAuth`(登录 + 权限 + 角色 + safe),成功后 `syncExpressAuthState`
143
+ * 5. 任意异常通过 `next(err)` 交给 `xltErrorHandler`
144
+ */
145
+ function xltMiddleware(xlt, options = {}) {
146
+ return async (req, res, next) => {
147
+ const httpCtx = createExpressContext(req, res);
148
+ req._xltRouteMeta = {
149
+ ...req._xltRouteMeta,
150
+ ...resolveRouteAuthMeta(req, options)
151
+ };
152
+ if (!shouldCheckLogin(req, xlt.config)) return next();
153
+ try {
154
+ await runAuth(xlt, httpCtx, req);
155
+ syncExpressAuthState(req, httpCtx);
156
+ next();
157
+ } catch (err) {
158
+ next(err);
159
+ }
160
+ };
161
+ }
162
+
163
+ //#endregion
164
+ //#region src/middleware/ignore-auth.ts
165
+ /**
166
+ * 路由级 helper:标记当前路由忽略登录校验(黑名单模式下放行)。
167
+ *
168
+ * 仅写入 `req._xltRouteMeta`,因此必须在同一条 route chain 中位于 `xltMiddleware` 之前才有效。
169
+ * 推荐主路径仍是 `xltMiddleware` 的 `ignore` / `policies` 选项。
170
+ */
171
+ function ignoreAuth() {
172
+ return (req, _res, next) => {
173
+ req._xltRouteMeta = {
174
+ ...req._xltRouteMeta,
175
+ ignore: true
176
+ };
177
+ next();
178
+ };
179
+ }
180
+
181
+ //#endregion
182
+ //#region src/middleware/require-login.ts
183
+ /**
184
+ * 路由级 helper:标记当前路由需要登录(白名单模式下开启校验)。
185
+ *
186
+ * 仅写入 `req._xltRouteMeta`,必须位于 `xltMiddleware` 之前才生效。
187
+ */
188
+ function requireLogin() {
189
+ return (req, _res, next) => {
190
+ req._xltRouteMeta = {
191
+ ...req._xltRouteMeta,
192
+ requireLogin: true
193
+ };
194
+ next();
195
+ };
196
+ }
197
+
198
+ //#endregion
199
+ //#region src/middleware/check-permission.ts
200
+ /**
201
+ * 路由级 helper:声明当前路由所需权限。
202
+ *
203
+ * 仅写入 `req._xltRouteMeta.permissions`,必须位于 `xltMiddleware` 之前才生效。
204
+ */
205
+ function checkPermission(permission, mode = XltMode$1.AND) {
206
+ return (req, _res, next) => {
207
+ const list = Array.isArray(permission) ? permission : [permission];
208
+ req._xltRouteMeta = {
209
+ ...req._xltRouteMeta,
210
+ permissions: {
211
+ list,
212
+ mode
213
+ }
214
+ };
215
+ next();
216
+ };
217
+ }
218
+
219
+ //#endregion
220
+ //#region src/middleware/check-role.ts
221
+ /**
222
+ * 路由级 helper:声明当前路由所需角色。
223
+ *
224
+ * 仅写入 `req._xltRouteMeta.roles`,必须位于 `xltMiddleware` 之前才生效。
225
+ */
226
+ function checkRole(role, mode = XltMode$1.AND) {
227
+ return (req, _res, next) => {
228
+ const list = Array.isArray(role) ? role : [role];
229
+ req._xltRouteMeta = {
230
+ ...req._xltRouteMeta,
231
+ roles: {
232
+ list,
233
+ mode
234
+ }
235
+ };
236
+ next();
237
+ };
238
+ }
239
+
240
+ //#endregion
241
+ //#region src/middleware/check-safe.ts
242
+ /**
243
+ * 路由级 helper:声明当前路由需要二级认证安全窗口。
244
+ *
245
+ * 仅写入 `req._xltRouteMeta.safeBusiness`,必须位于 `xltMiddleware` 之前才生效。
246
+ */
247
+ function checkSafe(business) {
248
+ return (req, _res, next) => {
249
+ req._xltRouteMeta = {
250
+ ...req._xltRouteMeta,
251
+ safeBusiness: business
252
+ };
253
+ next();
254
+ };
255
+ }
256
+
257
+ //#endregion
258
+ //#region src/error/map-xlt-error.ts
259
+ /**
260
+ * 将 core 鉴权异常映射为 HTTP 状态码 + JSON body。
261
+ * 非 xlt-token 异常返回 `null`,交由调用方继续向后传递。
262
+ */
263
+ function mapXltError(err) {
264
+ if (err instanceof NotLoginException$1) return {
265
+ status: 401,
266
+ body: {
267
+ statusCode: 401,
268
+ code: err.code,
269
+ type: err.type,
270
+ message: err.message,
271
+ token: err.token
272
+ }
273
+ };
274
+ if (err instanceof NotPermissionException$1) return {
275
+ status: 403,
276
+ body: {
277
+ statusCode: 403,
278
+ code: err.code,
279
+ permission: err.permission,
280
+ mode: err.mode,
281
+ message: err.message
282
+ }
283
+ };
284
+ if (err instanceof NotRoleException$1) return {
285
+ status: 403,
286
+ body: {
287
+ statusCode: 403,
288
+ code: err.code,
289
+ role: err.role,
290
+ mode: err.mode,
291
+ message: err.message
292
+ }
293
+ };
294
+ if (err instanceof NotSafeException$1) return {
295
+ status: 403,
296
+ body: {
297
+ statusCode: 403,
298
+ code: err.code,
299
+ business: err.business,
300
+ message: err.message
301
+ }
302
+ };
303
+ return null;
304
+ }
305
+
306
+ //#endregion
307
+ //#region src/error/xlt-error-handler.ts
308
+ /**
309
+ * 四参数 Express 错误中间件,挂在路由链末尾,将 core 鉴权异常转为 401/403 JSON。
310
+ * 非 xlt-token 异常透传给下一个错误处理器。
311
+ *
312
+ * @example
313
+ * app.use(xltErrorHandler());
314
+ */
315
+ function xltErrorHandler() {
316
+ return (err, _req, res, next) => {
317
+ const mapped = mapXltError(err);
318
+ if (!mapped) {
319
+ next(err);
320
+ return;
321
+ }
322
+ res.status(mapped.status).json(mapped.body);
323
+ };
324
+ }
325
+
326
+ //#endregion
327
+ export { DEFAULT_XLT_TOKEN_CONFIG, MemoryStore, NotLoginException, NotLoginType, NotPermissionException, NotRoleException, NotSafeException, StpLogic, StpPermLogic, StpUtil, UuidStrategy, XLT_STP_INTERFACE, XLT_TOKEN_CONFIG, XLT_TOKEN_HOOKS, XLT_TOKEN_STORE, XLT_TOKEN_STRATEGY, XltError, XltMode, XltSession, checkPermission, checkRole, checkSafe, createExpressContext, createMockHttpContext, createXltToken, ignoreAuth, matchPermission, requireLogin, resolveRouteAuthMeta, runAuth, setStpLogic, setStpPermLogic, shouldCheckLogin, syncExpressAuthState, xltErrorHandler, xltMiddleware };
328
+ //# sourceMappingURL=index.mjs.map