@xlt-token/nestjs 1.0.0-rc.3 → 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.
- package/README.md +22 -1
- package/dist/index.cjs +24 -1
- package/dist/index.mjs +24 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -2
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@ NestJS integration for [xlt-token](https://github.com/xiaoLangtou/xlt-token).
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
7
7
|
```bash
|
|
8
|
-
pnpm add @xlt-token/nestjs
|
|
8
|
+
pnpm add @xlt-token/nestjs
|
|
9
9
|
```
|
|
10
10
|
|
|
11
11
|
## Usage
|
|
@@ -20,6 +20,27 @@ import { XltTokenModule, XltTokenGuard } from '@xlt-token/nestjs';
|
|
|
20
20
|
export class AppModule {}
|
|
21
21
|
```
|
|
22
22
|
|
|
23
|
+
## Fastify
|
|
24
|
+
|
|
25
|
+
同时支持 Express 与 Fastify 适配器,守卫与装饰器无需改动。
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
import { FastifyAdapter, NestFastifyApplication } from '@nestjs/platform-fastify';
|
|
29
|
+
|
|
30
|
+
const app = await NestFactory.create<NestFastifyApplication>(
|
|
31
|
+
AppModule,
|
|
32
|
+
new FastifyAdapter(),
|
|
33
|
+
);
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
- Header / Query 模式开箱即用。
|
|
37
|
+
- Cookie 模式需先注册 `@fastify/cookie` 插件,否则无法读写 cookie:
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
import fastifyCookie from '@fastify/cookie';
|
|
41
|
+
await app.register(fastifyCookie);
|
|
42
|
+
```
|
|
43
|
+
|
|
23
44
|
## Documentation
|
|
24
45
|
|
|
25
46
|
https://xiaolangtou.github.io/xlt-token/
|
package/dist/index.cjs
CHANGED
|
@@ -403,8 +403,31 @@ var NotSafeException = class extends _nestjs_common.ForbiddenException {
|
|
|
403
403
|
|
|
404
404
|
//#endregion
|
|
405
405
|
//#region src/http/nest-bridge.ts
|
|
406
|
+
/**
|
|
407
|
+
* Fastify reply 的写回 API 与 Express response 不同:
|
|
408
|
+
* - 写 header:Express 用 `res.setHeader(n, v)`,Fastify 用 `reply.header(n, v)`
|
|
409
|
+
* - 写 cookie:Express 用 `res.cookie(n, v, o)`,Fastify 用 `reply.setCookie(n, v, o)`
|
|
410
|
+
*
|
|
411
|
+
* 这里把任意一种 response 归一化成 core 期望的 {@link ExpressLikeResponse} 形态,
|
|
412
|
+
* 让核心层无需感知底层 HTTP 平台。读取侧(headers/cookies/query)两个平台形态一致,
|
|
413
|
+
* 直接复用 core 的 createExpressContext。
|
|
414
|
+
*/
|
|
415
|
+
function normalizeResponse(res) {
|
|
416
|
+
return {
|
|
417
|
+
setHeader(name, value) {
|
|
418
|
+
if (typeof res?.setHeader === "function") res.setHeader(name, value);
|
|
419
|
+
else if (typeof res?.header === "function") res.header(name, value);
|
|
420
|
+
else throw new Error("xlt-token: 当前 response 不支持写入 header(既无 setHeader 也无 header 方法)");
|
|
421
|
+
},
|
|
422
|
+
cookie(name, value, options) {
|
|
423
|
+
if (typeof res?.cookie === "function") res.cookie(name, value, options);
|
|
424
|
+
else if (typeof res?.setCookie === "function") res.setCookie(name, value, options);
|
|
425
|
+
else throw new Error("xlt-token: 当前 response 不支持写入 cookie。若使用 Fastify,请先注册 @fastify/cookie 插件。");
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
}
|
|
406
429
|
function createNestHttpContext(req, res) {
|
|
407
|
-
return (0, _xlt_token_core.createExpressContext)(req, res);
|
|
430
|
+
return (0, _xlt_token_core.createExpressContext)(req, normalizeResponse(res));
|
|
408
431
|
}
|
|
409
432
|
function rethrowCoreAuthException(error) {
|
|
410
433
|
if (error instanceof _xlt_token_core.NotLoginException) throw new NotLoginException(error.type, error.token);
|
package/dist/index.mjs
CHANGED
|
@@ -402,8 +402,31 @@ var NotSafeException = class extends ForbiddenException {
|
|
|
402
402
|
|
|
403
403
|
//#endregion
|
|
404
404
|
//#region src/http/nest-bridge.ts
|
|
405
|
+
/**
|
|
406
|
+
* Fastify reply 的写回 API 与 Express response 不同:
|
|
407
|
+
* - 写 header:Express 用 `res.setHeader(n, v)`,Fastify 用 `reply.header(n, v)`
|
|
408
|
+
* - 写 cookie:Express 用 `res.cookie(n, v, o)`,Fastify 用 `reply.setCookie(n, v, o)`
|
|
409
|
+
*
|
|
410
|
+
* 这里把任意一种 response 归一化成 core 期望的 {@link ExpressLikeResponse} 形态,
|
|
411
|
+
* 让核心层无需感知底层 HTTP 平台。读取侧(headers/cookies/query)两个平台形态一致,
|
|
412
|
+
* 直接复用 core 的 createExpressContext。
|
|
413
|
+
*/
|
|
414
|
+
function normalizeResponse(res) {
|
|
415
|
+
return {
|
|
416
|
+
setHeader(name, value) {
|
|
417
|
+
if (typeof res?.setHeader === "function") res.setHeader(name, value);
|
|
418
|
+
else if (typeof res?.header === "function") res.header(name, value);
|
|
419
|
+
else throw new Error("xlt-token: 当前 response 不支持写入 header(既无 setHeader 也无 header 方法)");
|
|
420
|
+
},
|
|
421
|
+
cookie(name, value, options) {
|
|
422
|
+
if (typeof res?.cookie === "function") res.cookie(name, value, options);
|
|
423
|
+
else if (typeof res?.setCookie === "function") res.setCookie(name, value, options);
|
|
424
|
+
else throw new Error("xlt-token: 当前 response 不支持写入 cookie。若使用 Fastify,请先注册 @fastify/cookie 插件。");
|
|
425
|
+
}
|
|
426
|
+
};
|
|
427
|
+
}
|
|
405
428
|
function createNestHttpContext(req, res) {
|
|
406
|
-
return createExpressContext$1(req, res);
|
|
429
|
+
return createExpressContext$1(req, normalizeResponse(res));
|
|
407
430
|
}
|
|
408
431
|
function rethrowCoreAuthException(error) {
|
|
409
432
|
if (error instanceof NotLoginException$1) throw new NotLoginException(error.type, error.token);
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["XLT_TOKEN_STORE","MemoryStore","XLT_TOKEN_STRATEGY","UuidStrategy","XLT_STP_INTERFACE","XLT_TOKEN_HOOKS","StpLogic","XLT_TOKEN_CONFIG","StpPermLogic","DEFAULT_XLT_TOKEN_CONFIG","XLT_TOKEN_CONFIG","XltMode","XltMode","NotLoginType","createExpressContext","CoreNotLoginException","CoreNotPermissionException","CoreNotRoleException","CoreNotSafeException","XLT_TOKEN_CONFIG","CoreNotLoginException","XLT_TOKEN_CONFIG"],"sources":["../src/xlt-token.module.ts","../src/store/redis-store.ts","../src/token/jwt-strategy.ts","../src/decorators/xlt-check-login.decorator.ts","../src/decorators/xlt-ignore.decorator.ts","../src/decorators/login-id.decorator.ts","../src/decorators/token-value.decorator.ts","../src/decorators/xlt-check-permission.decorator.ts","../src/decorators/xlt-check-role.decorator.ts","../src/decorators/xlt-check-safe.decorator.ts","../src/exceptions/not-login.exception.ts","../src/exceptions/not-permission.exception.ts","../src/exceptions/not-role.exception.ts","../src/exceptions/not-safe.exception.ts","../src/http/nest-bridge.ts","../src/guards/xlt-token.guard.ts","../src/guards/xlt-abstract-login.guard.ts"],"sourcesContent":["import { Module, ModuleMetadata, Provider } from '@nestjs/common';\nimport {\n DEFAULT_XLT_TOKEN_CONFIG,\n MemoryStore,\n StpInterface,\n StpLogic,\n StpPermLogic,\n TokenStrategy,\n UuidStrategy,\n XLT_STP_INTERFACE,\n XLT_TOKEN_CONFIG,\n XLT_TOKEN_HOOKS,\n XLT_TOKEN_STORE,\n XLT_TOKEN_STRATEGY,\n XltHooks,\n XltTokenConfig,\n XltTokenStore,\n setStpLogic,\n setStpPermLogic,\n} from '@xlt-token/core';\n\nexport interface XltTokenModuleOptions {\n config?: Partial<XltTokenConfig>;\n store?: { useClass: new (...args: any[]) => XltTokenStore } | { useValue: XltTokenStore };\n strategy?: { useClass: new (...args: any[]) => TokenStrategy };\n isGlobal?: boolean;\n providers?: Provider[];\n stpInterface?: new (...args: any[]) => StpInterface;\n hooks?: XltHooks;\n}\n\nexport interface XltTokenModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {\n useFactory: (...args: any[]) => Promise<XltTokenModuleOptions> | XltTokenModuleOptions;\n inject?: any[];\n store?: { useClass: new (...args: any[]) => XltTokenStore } | { useValue: XltTokenStore };\n strategy?: { useClass: new (...args: any[]) => TokenStrategy };\n isGlobal?: boolean;\n providers?: Provider[];\n stpInterface?: new (...args: any[]) => StpInterface;\n hooks?: XltHooks;\n}\n\n@Module({})\nexport class XltTokenModule {\n private static createStoreProvider(\n store?: XltTokenModuleOptions['store'],\n ): Provider {\n if (!store) return { provide: XLT_TOKEN_STORE, useClass: MemoryStore };\n return 'useClass' in store\n ? { provide: XLT_TOKEN_STORE, useClass: store.useClass }\n : { provide: XLT_TOKEN_STORE, useValue: store.useValue };\n }\n\n private static createStrategyProvider(\n strategy?: XltTokenModuleOptions['strategy'],\n ): Provider {\n return strategy?.useClass\n ? { provide: XLT_TOKEN_STRATEGY, useClass: strategy.useClass }\n : { provide: XLT_TOKEN_STRATEGY, useClass: UuidStrategy };\n }\n\n private static createStpInterfaceProvider(\n stpInterface?: new (...args: any[]) => StpInterface,\n ): Provider {\n if (stpInterface) return { provide: XLT_STP_INTERFACE, useClass: stpInterface };\n return {\n provide: XLT_STP_INTERFACE,\n useValue: {\n getPermissionList: () => { throw new Error('StpInterface not registered: getPermissionList'); },\n getRoleList: () => { throw new Error('StpInterface not registered: getRoleList'); },\n },\n };\n }\n\n private static createHooksProvider(\n hooks?: XltTokenModuleOptions['hooks'],\n ): Provider {\n return { provide: XLT_TOKEN_HOOKS, useValue: hooks ?? {} };\n }\n\n private static readonly stpLogicProvider: Provider = {\n provide: StpLogic,\n useFactory: (\n config: XltTokenConfig,\n store: XltTokenStore,\n strategy: TokenStrategy,\n hooks: XltHooks,\n ) => new StpLogic(config, store, strategy, hooks),\n inject: [XLT_TOKEN_CONFIG, XLT_TOKEN_STORE, XLT_TOKEN_STRATEGY, XLT_TOKEN_HOOKS],\n };\n\n private static readonly stpPermLogicProvider: Provider = {\n provide: StpPermLogic,\n useFactory: (\n stpInterface: StpInterface,\n store: XltTokenStore,\n config: XltTokenConfig,\n ) => new StpPermLogic(stpInterface, store, config),\n inject: [XLT_STP_INTERFACE, XLT_TOKEN_STORE, XLT_TOKEN_CONFIG],\n };\n\n private static readonly initProvider: Provider = {\n provide: 'XLT_TOKEN_INIT',\n useFactory: (stpLogic: StpLogic, stpPermLogic: StpPermLogic) => {\n setStpLogic(stpLogic);\n setStpPermLogic(stpPermLogic);\n return true;\n },\n inject: [StpLogic, StpPermLogic],\n };\n\n private static readonly moduleExports = [XLT_TOKEN_CONFIG, XLT_TOKEN_STORE, XLT_TOKEN_STRATEGY, StpLogic, StpPermLogic];\n\n static forRoot(options: XltTokenModuleOptions = {}) {\n const { config: userConfig, store, strategy, isGlobal = false, providers = [], stpInterface } = options;\n\n return {\n module: XltTokenModule,\n providers: [\n { provide: XLT_TOKEN_CONFIG, useValue: { ...DEFAULT_XLT_TOKEN_CONFIG, ...userConfig } },\n XltTokenModule.createStoreProvider(store),\n XltTokenModule.createStrategyProvider(strategy),\n XltTokenModule.createStpInterfaceProvider(stpInterface),\n XltTokenModule.createHooksProvider(options.hooks),\n XltTokenModule.stpLogicProvider,\n XltTokenModule.stpPermLogicProvider,\n XltTokenModule.initProvider,\n ...providers,\n ],\n exports: XltTokenModule.moduleExports,\n global: isGlobal,\n };\n }\n\n static forRootAsync(options: XltTokenModuleAsyncOptions) {\n const { useFactory, inject = [], imports = [], store, strategy, isGlobal = false, providers = [], stpInterface } = options;\n\n return {\n module: XltTokenModule,\n imports,\n providers: [\n {\n provide: XLT_TOKEN_CONFIG,\n useFactory: async (...args: any[]) => {\n const { config = {} } = await useFactory(...args);\n return { ...DEFAULT_XLT_TOKEN_CONFIG, ...config };\n },\n inject,\n },\n XltTokenModule.createStoreProvider(store),\n XltTokenModule.createStrategyProvider(strategy),\n XltTokenModule.createStpInterfaceProvider(stpInterface),\n XltTokenModule.createHooksProvider(options.hooks),\n XltTokenModule.stpLogicProvider,\n XltTokenModule.stpPermLogicProvider,\n XltTokenModule.initProvider,\n ...providers,\n ],\n exports: XltTokenModule.moduleExports,\n global: isGlobal,\n };\n }\n}\n","import { XltTokenStore } from '@xlt-token/core';\nimport { Inject, Injectable } from '@nestjs/common';\n\n\nexport const XLT_REDIS_CLIENT = 'XLT_REDIS_CLIENT';\n\n\n@Injectable()\nexport class RedisStore implements XltTokenStore {\n\n constructor(\n @Inject(XLT_REDIS_CLIENT)\n private readonly redisClient: any,\n ) {\n\n }\n\n\n async get(key:string):Promise<string | null> {\n return this.redisClient.get(key);\n }\n\n\n async set(key:string, value:string, timeoutSec:number):Promise<void> {\n if (timeoutSec === -1){\n await this.redisClient.set(key, value);\n }else {\n await this.redisClient.set(key, value, {EX: timeoutSec});\n }\n }\n\n\n async delete(key:string):Promise<void> {\n await this.redisClient.del(key);\n }\n\n\n async update(key:string, value:string):Promise<void> {\n const result = await this.redisClient.set(key, value,{XX:true,KEEPTTL:true})\n if (result ===null){\n throw new Error(`Key not found: ${key}`);\n }\n }\n\n\n async has(key:string):Promise<boolean> {\n const result = await this.redisClient.exists(key);\n return result === 1;\n }\n\n\n async updateTimeout(key:string, timeoutSec:number):Promise<void> {\n const exists = await this.redisClient.exists(key);\n\n if (!exists) {\n throw new Error(`Key not found: ${key}`);\n }\n\n if (timeoutSec === -1) {\n await this.redisClient.persist(key);\n }else {\n await this.redisClient.expire(key, timeoutSec);\n }\n\n }\n\n async getTimeout(key:string):Promise<number> {\n const result = await this.redisClient.ttl(key);\n // Redis TTL 返回值约定:\n // -2 = key 不存在\n // -1 = key 存在但无过期时间(永久)\n // >0 = 剩余秒数\n // 恰好与 XltTokenStore 接口约定一致\n return result;\n }\n\n async keys(pattern: string): Promise<string[]> {\n const result: string[] = [];\n let cursor = 0;\n do {\n const reply = await this.redisClient.scan(cursor, { MATCH: pattern, COUNT: 100 });\n cursor = reply.cursor;\n result.push(...reply.keys);\n } while (cursor !== 0);\n return result;\n }\n}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport { XLT_TOKEN_CONFIG, XltTokenConfig } from '@xlt-token/core';\nimport type { TokenStrategy } from '@xlt-token/core';\nimport { sign, verify, JwtPayload } from \"jsonwebtoken\";\n\n@Injectable()\nexport class JwtStrategy implements TokenStrategy {\n constructor(\n @Inject(XLT_TOKEN_CONFIG) private readonly config: XltTokenConfig\n ) { }\n\n\n\n createToken(loginId: string, config: XltTokenConfig): string {\n const jwt = config.jwt!;\n const jti = crypto.randomUUID();\n\n\n return sign({\n sub: loginId, jti\n }, jwt.secret, {\n algorithm: jwt.algorithm ?? 'HS256',\n ...(jwt.issuer && { issuer: jwt.issuer }),\n ...(jwt.audience && { audience: jwt.audience }),\n ...(config.timeout > 0 && { expiresIn: config.timeout }),\n })\n\n }\n\n\n generateToken(payload: any): string {\n return sign(payload, this.config.jwt!.secret);\n }\n\n\n\n verifyToken(token: string): JwtPayload & { sub: string; jti: string } {\n return verify(token, this.config.jwt!.secret) as any;\n }\n\n}\n","// 登录校验装饰器\n\nimport { SetMetadata } from '@nestjs/common';\nimport { XLT_CHECK_LOGIN_KEY } from '@xlt-token/core';\n\n\n/**\n * 登录校验装饰器\n * @constructor\n */\nexport const XltCheckLogin = () => SetMetadata(XLT_CHECK_LOGIN_KEY, true);\n","// 忽略校验装饰器\n\nimport { SetMetadata } from '@nestjs/common';\nimport { XLT_IGNORE_KEY } from '@xlt-token/core';\n\nexport const XltIgnore = () => SetMetadata(XLT_IGNORE_KEY, true);\n","// 注入当前用户 ID\n\nimport { createParamDecorator, ExecutionContext } from '@nestjs/common';\n\n/**\n * 注入当前用户 ID\n * @constructor\n */\nexport const LoginId = createParamDecorator(\n (data: unknown, ctx: ExecutionContext) => {\n const request = ctx.switchToHttp().getRequest();\n return request.stpLoginId;\n },\n);\n","// 注入当前 Token\n\nimport { createParamDecorator, ExecutionContext } from '@nestjs/common';\n\n\n/**\n * 注入当前 Token\n * @constructor\n */\nexport const TokenValue = createParamDecorator((data: any, ctx: ExecutionContext) => {\n const request = ctx.switchToHttp().getRequest();\n return request.stpToken;\n});\n","import { XLT_PERMISSION_KEY, XltMode } from '@xlt-token/core';\nimport { SetMetadata } from '@nestjs/common';\n\n\n/**\n * 权限检查装饰器\n * @param {string | string[]} permissions 权限列表\n * @param {Object} [options] 模式选项\n * @param {XltMode} [options.mode] 模式选项\n * @constructor\n */\nexport const XltCheckPermission = (permissions: string | string[], options?: { mode: XltMode; }) => {\n const perms = Array.isArray(permissions) ? permissions : [permissions];\n const mode = options?.mode ?? XltMode.AND;\n return SetMetadata(XLT_PERMISSION_KEY, { permissions: perms, mode });\n};\n","import { XLT_ROLE_KEY, XltMode } from '@xlt-token/core';\nimport { SetMetadata } from '@nestjs/common';\n\n\n/**\n * 角色检查装饰器\n * @param {string | string[]} roles 角色列表\n * @param {Object} [options] 模式选项\n * @param {XltMode} [options.mode] 模式选项\n * @constructor\n */\nexport const XltCheckRole = (roles: string | string[], options?: { mode: XltMode; }) => {\n const _roles = Array.isArray(roles) ? roles : [roles];\n const mode = options?.mode ?? XltMode.AND;\n return SetMetadata(XLT_ROLE_KEY, { roles: _roles, mode });\n\n};\n","import { SetMetadata } from \"@nestjs/common\"\n\nexport const XLT_CHECK_SAFE_KEY = 'XLT_CHECK_SAFE';\n\nexport const XltCheckSafe = (business: string) => {\n return SetMetadata(XLT_CHECK_SAFE_KEY, business);\n}\n","import { UnauthorizedException } from '@nestjs/common';\nimport { NotLoginType } from '@xlt-token/core';\n\nexport class NotLoginException extends UnauthorizedException {\n public readonly type: NotLoginType;\n public readonly token: string | undefined;\n\n constructor(type: NotLoginType, token?: string) {\n super({\n statusCode: 401,\n type,\n message: NotLoginException.describeType(type),\n });\n this.type = type;\n this.token = token;\n }\n\n private static describeType(type: NotLoginType): string {\n const map: Record<NotLoginType, string> = {\n [NotLoginType.NOT_TOKEN]: '未提供 Token',\n [NotLoginType.INVALID_TOKEN]: 'Token 无效',\n [NotLoginType.TOKEN_TIMEOUT]: 'Token 已过期',\n [NotLoginType.TOKEN_FREEZE]: 'Token 已被冻结',\n [NotLoginType.BE_REPLACED]: '已被顶下线',\n [NotLoginType.KICK_OUT]: '已被踢下线',\n };\n return map[type] ?? '未登录';\n }\n}\n\n","import { ForbiddenException } from '@nestjs/common';\nimport { XltMode } from '@xlt-token/core';\n\nexport class NotPermissionException extends ForbiddenException {\n public readonly permission: string | string[];\n public readonly mode: XltMode;\n\n constructor(permission: string | string[], mode: XltMode) {\n super({\n statusCode: 403,\n type: 'NOT_PERMISSION',\n message: `缺少权限: ${Array.isArray(permission) ? permission.join(', ') : permission}`,\n });\n this.permission = permission;\n this.mode = mode;\n }\n}\n","import { ForbiddenException } from '@nestjs/common';\nimport { XltMode } from '@xlt-token/core';\n\nexport class NotRoleException extends ForbiddenException {\n public readonly role: string | string[];\n public readonly mode: XltMode;\n\n constructor(role: string | string[], mode: XltMode) {\n super({\n statusCode: 403,\n type: 'NOT_ROLE',\n message: `缺少角色: ${Array.isArray(role) ? role.join(', ') : role}`,\n });\n this.role = role;\n this.mode = mode;\n }\n}\n","import { ForbiddenException } from \"@nestjs/common\";\n\nexport class NotSafeException extends ForbiddenException {\n readonly business: string;\n\n\n constructor(business: string) {\n super({\n statusCode: 403,\n type: 'NOT_SAFE',\n message: `二级认证未开启:${business}`,\n });\n this.business = business;\n }\n\n}\n","import {\n createExpressContext,\n NotLoginException as CoreNotLoginException,\n NotPermissionException as CoreNotPermissionException,\n NotRoleException as CoreNotRoleException,\n NotSafeException as CoreNotSafeException,\n} from '@xlt-token/core';\nimport { NotLoginException } from '../exceptions/not-login.exception.js';\nimport { NotPermissionException } from '../exceptions/not-permission.exception.js';\nimport { NotRoleException } from '../exceptions/not-role.exception.js';\nimport { NotSafeException } from '../exceptions/not-safe.exception.js';\n\nexport function createNestHttpContext(req: any, res: any) {\n return createExpressContext(req, res);\n}\n\nexport function rethrowCoreAuthException(error: unknown): never {\n if (error instanceof CoreNotLoginException) {\n throw new NotLoginException(error.type, error.token);\n }\n if (error instanceof CoreNotPermissionException) {\n throw new NotPermissionException(error.permission, error.mode);\n }\n if (error instanceof CoreNotRoleException) {\n throw new NotRoleException(error.role, error.mode);\n }\n if (error instanceof CoreNotSafeException) {\n throw new NotSafeException(error.business);\n }\n throw error;\n}\n","// 全局守卫\n\nimport { CanActivate, ExecutionContext, Inject, Injectable, Optional } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport {\n type AuthResult,\n StpLogic,\n StpPermLogic,\n XLT_CHECK_LOGIN_KEY,\n XLT_IGNORE_KEY,\n XLT_PERMISSION_KEY,\n XLT_ROLE_KEY,\n XLT_TOKEN_CONFIG,\n type XltTokenConfig,\n} from '@xlt-token/core';\nimport { XLT_CHECK_SAFE_KEY } from '../decorators/xlt-check-safe.decorator.js';\nimport { createNestHttpContext, rethrowCoreAuthException } from '../http/nest-bridge.js';\n\n@Injectable()\nexport class XltTokenGuard implements CanActivate {\n constructor(\n private readonly reflector: Reflector,\n @Inject(XLT_TOKEN_CONFIG) private readonly config: XltTokenConfig,\n private readonly stpLogic: StpLogic,\n @Optional() private readonly stpPermLogic?: StpPermLogic,\n ) {\n }\n\n async canActivate(context: ExecutionContext): Promise<boolean> {\n if (!this.requiresLogin(context)) return true;\n\n const request = context.switchToHttp().getRequest();\n const response = context.switchToHttp().getResponse();\n\n let result: AuthResult;\n try {\n result = await this.stpLogic.checkLogin(createNestHttpContext(request, response));\n } catch (error) {\n rethrowCoreAuthException(error);\n }\n\n const business = this.getBusiness(context);\n request.stpLoginId = result.loginId;\n request.stpToken = result.token;\n\n try {\n if (this.stpPermLogic) {\n const handler = context.getHandler();\n const cls = context.getClass();\n\n const permMeta = this.reflector.getAllAndOverride(XLT_PERMISSION_KEY, [handler, cls]);\n if (permMeta) {\n await this.stpPermLogic.checkPermission(result.loginId!, permMeta.permissions, permMeta.mode);\n }\n\n const roleMeta = this.reflector.getAllAndOverride(XLT_ROLE_KEY, [handler, cls]);\n if (roleMeta) {\n await this.stpPermLogic.checkRole(result.loginId!, roleMeta.roles, roleMeta.mode);\n }\n }\n\n if (business) {\n await this.stpLogic.checkSafe(result.token!, business);\n }\n } catch (error) {\n rethrowCoreAuthException(error);\n }\n\n return true;\n }\n\n private requiresLogin(context: ExecutionContext): boolean {\n const isIgnored = this.reflector.getAllAndOverride<boolean>(XLT_IGNORE_KEY, [\n context.getHandler(),\n context.getClass(),\n ]);\n\n if (this.config.defaultCheck) {\n return !isIgnored;\n }\n\n const shouldCheck = this.reflector.getAllAndOverride<boolean>(XLT_CHECK_LOGIN_KEY, [\n context.getHandler(),\n context.getClass(),\n ]);\n return shouldCheck ?? false;\n }\n\n private getBusiness(context: ExecutionContext): string {\n return this.reflector.getAllAndOverride<string>(XLT_CHECK_SAFE_KEY, [\n context.getHandler(),\n context.getClass(),\n ]);\n }\n}\n","import { CanActivate, ExecutionContext, Inject, Injectable } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport {\n NotLoginException as CoreNotLoginException,\n NotLoginType,\n StpLogic,\n XLT_CHECK_LOGIN_KEY,\n XLT_IGNORE_KEY,\n XLT_TOKEN_CONFIG,\n type XltTokenConfig,\n} from '@xlt-token/core';\nimport { NotLoginException } from '../exceptions/not-login.exception.js';\nimport { createNestHttpContext } from '../http/nest-bridge.js';\n\n@Injectable()\nexport abstract class XltAbstractLoginGuard implements CanActivate {\n protected constructor(\n protected readonly reflector: Reflector,\n @Inject(XLT_TOKEN_CONFIG) protected readonly config: XltTokenConfig,\n protected readonly stpLogic: StpLogic,\n ) {}\n\n async canActivate(ctx: ExecutionContext): Promise<boolean> {\n if (!this.requiresLogin(ctx)) return true;\n\n const request = ctx.switchToHttp().getRequest();\n const response = ctx.switchToHttp().getResponse();\n\n let result: { ok: boolean; loginId?: string; token?: string; reason?: NotLoginType };\n try {\n result = await this.stpLogic.checkLogin(createNestHttpContext(request, response));\n } catch (err) {\n if (err instanceof CoreNotLoginException) {\n await this.onAuthFail?.({ ok: false, reason: err.type, token: err.token }, request);\n throw new NotLoginException(err.type, err.token);\n }\n throw err;\n }\n\n request.stpLoginId = result.loginId;\n request.stpToken = result.token;\n await this.onAuthSuccess?.(result, request);\n return true;\n }\n\n protected requiresLogin(ctx: ExecutionContext): boolean {\n const isIgnored = this.reflector.getAllAndOverride<boolean>(XLT_IGNORE_KEY, [ctx.getHandler(), ctx.getClass()]);\n\n if (this.config.defaultCheck) return !isIgnored;\n\n return this.reflector.getAllAndOverride<boolean>(XLT_CHECK_LOGIN_KEY, [ctx.getHandler(), ctx.getClass()]) ?? false;\n }\n\n protected onAuthSuccess?(\n result: {\n ok: boolean;\n loginId?: string | undefined;\n token?: string | undefined;\n reason?: NotLoginType | undefined;\n },\n request: any,\n ): void | Promise<void>;\n\n protected onAuthFail?(\n result: {\n ok: boolean;\n loginId?: string | undefined;\n token?: string | undefined;\n reason?: NotLoginType | undefined;\n },\n request: any,\n ): void | Promise<void>;\n\n protected onPermissionDenied?(\n result: {\n ok: boolean;\n loginId?: string | undefined;\n token?: string | undefined;\n reason?: NotLoginType | undefined;\n },\n request: any,\n ): void | Promise<void>;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["XLT_TOKEN_STORE","MemoryStore","XLT_TOKEN_STRATEGY","UuidStrategy","XLT_STP_INTERFACE","XLT_TOKEN_HOOKS","StpLogic","XLT_TOKEN_CONFIG","StpPermLogic","DEFAULT_XLT_TOKEN_CONFIG","XLT_TOKEN_CONFIG","XltMode","XltMode","NotLoginType","createExpressContext","CoreNotLoginException","CoreNotPermissionException","CoreNotRoleException","CoreNotSafeException","XLT_TOKEN_CONFIG","CoreNotLoginException","XLT_TOKEN_CONFIG"],"sources":["../src/xlt-token.module.ts","../src/store/redis-store.ts","../src/token/jwt-strategy.ts","../src/decorators/xlt-check-login.decorator.ts","../src/decorators/xlt-ignore.decorator.ts","../src/decorators/login-id.decorator.ts","../src/decorators/token-value.decorator.ts","../src/decorators/xlt-check-permission.decorator.ts","../src/decorators/xlt-check-role.decorator.ts","../src/decorators/xlt-check-safe.decorator.ts","../src/exceptions/not-login.exception.ts","../src/exceptions/not-permission.exception.ts","../src/exceptions/not-role.exception.ts","../src/exceptions/not-safe.exception.ts","../src/http/nest-bridge.ts","../src/guards/xlt-token.guard.ts","../src/guards/xlt-abstract-login.guard.ts"],"sourcesContent":["import { Module, ModuleMetadata, Provider } from '@nestjs/common';\nimport {\n DEFAULT_XLT_TOKEN_CONFIG,\n MemoryStore,\n StpInterface,\n StpLogic,\n StpPermLogic,\n TokenStrategy,\n UuidStrategy,\n XLT_STP_INTERFACE,\n XLT_TOKEN_CONFIG,\n XLT_TOKEN_HOOKS,\n XLT_TOKEN_STORE,\n XLT_TOKEN_STRATEGY,\n XltHooks,\n XltTokenConfig,\n XltTokenStore,\n setStpLogic,\n setStpPermLogic,\n} from '@xlt-token/core';\n\nexport interface XltTokenModuleOptions {\n config?: Partial<XltTokenConfig>;\n store?: { useClass: new (...args: any[]) => XltTokenStore } | { useValue: XltTokenStore };\n strategy?: { useClass: new (...args: any[]) => TokenStrategy };\n isGlobal?: boolean;\n providers?: Provider[];\n stpInterface?: new (...args: any[]) => StpInterface;\n hooks?: XltHooks;\n}\n\nexport interface XltTokenModuleAsyncOptions extends Pick<ModuleMetadata, 'imports'> {\n useFactory: (...args: any[]) => Promise<XltTokenModuleOptions> | XltTokenModuleOptions;\n inject?: any[];\n store?: { useClass: new (...args: any[]) => XltTokenStore } | { useValue: XltTokenStore };\n strategy?: { useClass: new (...args: any[]) => TokenStrategy };\n isGlobal?: boolean;\n providers?: Provider[];\n stpInterface?: new (...args: any[]) => StpInterface;\n hooks?: XltHooks;\n}\n\n@Module({})\nexport class XltTokenModule {\n private static createStoreProvider(\n store?: XltTokenModuleOptions['store'],\n ): Provider {\n if (!store) return { provide: XLT_TOKEN_STORE, useClass: MemoryStore };\n return 'useClass' in store\n ? { provide: XLT_TOKEN_STORE, useClass: store.useClass }\n : { provide: XLT_TOKEN_STORE, useValue: store.useValue };\n }\n\n private static createStrategyProvider(\n strategy?: XltTokenModuleOptions['strategy'],\n ): Provider {\n return strategy?.useClass\n ? { provide: XLT_TOKEN_STRATEGY, useClass: strategy.useClass }\n : { provide: XLT_TOKEN_STRATEGY, useClass: UuidStrategy };\n }\n\n private static createStpInterfaceProvider(\n stpInterface?: new (...args: any[]) => StpInterface,\n ): Provider {\n if (stpInterface) return { provide: XLT_STP_INTERFACE, useClass: stpInterface };\n return {\n provide: XLT_STP_INTERFACE,\n useValue: {\n getPermissionList: () => { throw new Error('StpInterface not registered: getPermissionList'); },\n getRoleList: () => { throw new Error('StpInterface not registered: getRoleList'); },\n },\n };\n }\n\n private static createHooksProvider(\n hooks?: XltTokenModuleOptions['hooks'],\n ): Provider {\n return { provide: XLT_TOKEN_HOOKS, useValue: hooks ?? {} };\n }\n\n private static readonly stpLogicProvider: Provider = {\n provide: StpLogic,\n useFactory: (\n config: XltTokenConfig,\n store: XltTokenStore,\n strategy: TokenStrategy,\n hooks: XltHooks,\n ) => new StpLogic(config, store, strategy, hooks),\n inject: [XLT_TOKEN_CONFIG, XLT_TOKEN_STORE, XLT_TOKEN_STRATEGY, XLT_TOKEN_HOOKS],\n };\n\n private static readonly stpPermLogicProvider: Provider = {\n provide: StpPermLogic,\n useFactory: (\n stpInterface: StpInterface,\n store: XltTokenStore,\n config: XltTokenConfig,\n ) => new StpPermLogic(stpInterface, store, config),\n inject: [XLT_STP_INTERFACE, XLT_TOKEN_STORE, XLT_TOKEN_CONFIG],\n };\n\n private static readonly initProvider: Provider = {\n provide: 'XLT_TOKEN_INIT',\n useFactory: (stpLogic: StpLogic, stpPermLogic: StpPermLogic) => {\n setStpLogic(stpLogic);\n setStpPermLogic(stpPermLogic);\n return true;\n },\n inject: [StpLogic, StpPermLogic],\n };\n\n private static readonly moduleExports = [XLT_TOKEN_CONFIG, XLT_TOKEN_STORE, XLT_TOKEN_STRATEGY, StpLogic, StpPermLogic];\n\n static forRoot(options: XltTokenModuleOptions = {}) {\n const { config: userConfig, store, strategy, isGlobal = false, providers = [], stpInterface } = options;\n\n return {\n module: XltTokenModule,\n providers: [\n { provide: XLT_TOKEN_CONFIG, useValue: { ...DEFAULT_XLT_TOKEN_CONFIG, ...userConfig } },\n XltTokenModule.createStoreProvider(store),\n XltTokenModule.createStrategyProvider(strategy),\n XltTokenModule.createStpInterfaceProvider(stpInterface),\n XltTokenModule.createHooksProvider(options.hooks),\n XltTokenModule.stpLogicProvider,\n XltTokenModule.stpPermLogicProvider,\n XltTokenModule.initProvider,\n ...providers,\n ],\n exports: XltTokenModule.moduleExports,\n global: isGlobal,\n };\n }\n\n static forRootAsync(options: XltTokenModuleAsyncOptions) {\n const { useFactory, inject = [], imports = [], store, strategy, isGlobal = false, providers = [], stpInterface } = options;\n\n return {\n module: XltTokenModule,\n imports,\n providers: [\n {\n provide: XLT_TOKEN_CONFIG,\n useFactory: async (...args: any[]) => {\n const { config = {} } = await useFactory(...args);\n return { ...DEFAULT_XLT_TOKEN_CONFIG, ...config };\n },\n inject,\n },\n XltTokenModule.createStoreProvider(store),\n XltTokenModule.createStrategyProvider(strategy),\n XltTokenModule.createStpInterfaceProvider(stpInterface),\n XltTokenModule.createHooksProvider(options.hooks),\n XltTokenModule.stpLogicProvider,\n XltTokenModule.stpPermLogicProvider,\n XltTokenModule.initProvider,\n ...providers,\n ],\n exports: XltTokenModule.moduleExports,\n global: isGlobal,\n };\n }\n}\n","import { XltTokenStore } from '@xlt-token/core';\nimport { Inject, Injectable } from '@nestjs/common';\n\n\nexport const XLT_REDIS_CLIENT = 'XLT_REDIS_CLIENT';\n\n\n@Injectable()\nexport class RedisStore implements XltTokenStore {\n\n constructor(\n @Inject(XLT_REDIS_CLIENT)\n private readonly redisClient: any,\n ) {\n\n }\n\n\n async get(key:string):Promise<string | null> {\n return this.redisClient.get(key);\n }\n\n\n async set(key:string, value:string, timeoutSec:number):Promise<void> {\n if (timeoutSec === -1){\n await this.redisClient.set(key, value);\n }else {\n await this.redisClient.set(key, value, {EX: timeoutSec});\n }\n }\n\n\n async delete(key:string):Promise<void> {\n await this.redisClient.del(key);\n }\n\n\n async update(key:string, value:string):Promise<void> {\n const result = await this.redisClient.set(key, value,{XX:true,KEEPTTL:true})\n if (result ===null){\n throw new Error(`Key not found: ${key}`);\n }\n }\n\n\n async has(key:string):Promise<boolean> {\n const result = await this.redisClient.exists(key);\n return result === 1;\n }\n\n\n async updateTimeout(key:string, timeoutSec:number):Promise<void> {\n const exists = await this.redisClient.exists(key);\n\n if (!exists) {\n throw new Error(`Key not found: ${key}`);\n }\n\n if (timeoutSec === -1) {\n await this.redisClient.persist(key);\n }else {\n await this.redisClient.expire(key, timeoutSec);\n }\n\n }\n\n async getTimeout(key:string):Promise<number> {\n const result = await this.redisClient.ttl(key);\n // Redis TTL 返回值约定:\n // -2 = key 不存在\n // -1 = key 存在但无过期时间(永久)\n // >0 = 剩余秒数\n // 恰好与 XltTokenStore 接口约定一致\n return result;\n }\n\n async keys(pattern: string): Promise<string[]> {\n const result: string[] = [];\n let cursor = 0;\n do {\n const reply = await this.redisClient.scan(cursor, { MATCH: pattern, COUNT: 100 });\n cursor = reply.cursor;\n result.push(...reply.keys);\n } while (cursor !== 0);\n return result;\n }\n}\n","import { Inject, Injectable } from \"@nestjs/common\";\nimport { XLT_TOKEN_CONFIG, XltTokenConfig } from '@xlt-token/core';\nimport type { TokenStrategy } from '@xlt-token/core';\nimport { sign, verify, JwtPayload } from \"jsonwebtoken\";\n\n@Injectable()\nexport class JwtStrategy implements TokenStrategy {\n constructor(\n @Inject(XLT_TOKEN_CONFIG) private readonly config: XltTokenConfig\n ) { }\n\n\n\n createToken(loginId: string, config: XltTokenConfig): string {\n const jwt = config.jwt!;\n const jti = crypto.randomUUID();\n\n\n return sign({\n sub: loginId, jti\n }, jwt.secret, {\n algorithm: jwt.algorithm ?? 'HS256',\n ...(jwt.issuer && { issuer: jwt.issuer }),\n ...(jwt.audience && { audience: jwt.audience }),\n ...(config.timeout > 0 && { expiresIn: config.timeout }),\n })\n\n }\n\n\n generateToken(payload: any): string {\n return sign(payload, this.config.jwt!.secret);\n }\n\n\n\n verifyToken(token: string): JwtPayload & { sub: string; jti: string } {\n return verify(token, this.config.jwt!.secret) as any;\n }\n\n}\n","// 登录校验装饰器\n\nimport { SetMetadata } from '@nestjs/common';\nimport { XLT_CHECK_LOGIN_KEY } from '@xlt-token/core';\n\n\n/**\n * 登录校验装饰器\n * @constructor\n */\nexport const XltCheckLogin = () => SetMetadata(XLT_CHECK_LOGIN_KEY, true);\n","// 忽略校验装饰器\n\nimport { SetMetadata } from '@nestjs/common';\nimport { XLT_IGNORE_KEY } from '@xlt-token/core';\n\nexport const XltIgnore = () => SetMetadata(XLT_IGNORE_KEY, true);\n","// 注入当前用户 ID\n\nimport { createParamDecorator, ExecutionContext } from '@nestjs/common';\n\n/**\n * 注入当前用户 ID\n * @constructor\n */\nexport const LoginId = createParamDecorator(\n (data: unknown, ctx: ExecutionContext) => {\n const request = ctx.switchToHttp().getRequest();\n return request.stpLoginId;\n },\n);\n","// 注入当前 Token\n\nimport { createParamDecorator, ExecutionContext } from '@nestjs/common';\n\n\n/**\n * 注入当前 Token\n * @constructor\n */\nexport const TokenValue = createParamDecorator((data: any, ctx: ExecutionContext) => {\n const request = ctx.switchToHttp().getRequest();\n return request.stpToken;\n});\n","import { XLT_PERMISSION_KEY, XltMode } from '@xlt-token/core';\nimport { SetMetadata } from '@nestjs/common';\n\n\n/**\n * 权限检查装饰器\n * @param {string | string[]} permissions 权限列表\n * @param {Object} [options] 模式选项\n * @param {XltMode} [options.mode] 模式选项\n * @constructor\n */\nexport const XltCheckPermission = (permissions: string | string[], options?: { mode: XltMode; }) => {\n const perms = Array.isArray(permissions) ? permissions : [permissions];\n const mode = options?.mode ?? XltMode.AND;\n return SetMetadata(XLT_PERMISSION_KEY, { permissions: perms, mode });\n};\n","import { XLT_ROLE_KEY, XltMode } from '@xlt-token/core';\nimport { SetMetadata } from '@nestjs/common';\n\n\n/**\n * 角色检查装饰器\n * @param {string | string[]} roles 角色列表\n * @param {Object} [options] 模式选项\n * @param {XltMode} [options.mode] 模式选项\n * @constructor\n */\nexport const XltCheckRole = (roles: string | string[], options?: { mode: XltMode; }) => {\n const _roles = Array.isArray(roles) ? roles : [roles];\n const mode = options?.mode ?? XltMode.AND;\n return SetMetadata(XLT_ROLE_KEY, { roles: _roles, mode });\n\n};\n","import { SetMetadata } from \"@nestjs/common\"\n\nexport const XLT_CHECK_SAFE_KEY = 'XLT_CHECK_SAFE';\n\nexport const XltCheckSafe = (business: string) => {\n return SetMetadata(XLT_CHECK_SAFE_KEY, business);\n}\n","import { UnauthorizedException } from '@nestjs/common';\nimport { NotLoginType } from '@xlt-token/core';\n\nexport class NotLoginException extends UnauthorizedException {\n public readonly type: NotLoginType;\n public readonly token: string | undefined;\n\n constructor(type: NotLoginType, token?: string) {\n super({\n statusCode: 401,\n type,\n message: NotLoginException.describeType(type),\n });\n this.type = type;\n this.token = token;\n }\n\n private static describeType(type: NotLoginType): string {\n const map: Record<NotLoginType, string> = {\n [NotLoginType.NOT_TOKEN]: '未提供 Token',\n [NotLoginType.INVALID_TOKEN]: 'Token 无效',\n [NotLoginType.TOKEN_TIMEOUT]: 'Token 已过期',\n [NotLoginType.TOKEN_FREEZE]: 'Token 已被冻结',\n [NotLoginType.BE_REPLACED]: '已被顶下线',\n [NotLoginType.KICK_OUT]: '已被踢下线',\n };\n return map[type] ?? '未登录';\n }\n}\n\n","import { ForbiddenException } from '@nestjs/common';\nimport { XltMode } from '@xlt-token/core';\n\nexport class NotPermissionException extends ForbiddenException {\n public readonly permission: string | string[];\n public readonly mode: XltMode;\n\n constructor(permission: string | string[], mode: XltMode) {\n super({\n statusCode: 403,\n type: 'NOT_PERMISSION',\n message: `缺少权限: ${Array.isArray(permission) ? permission.join(', ') : permission}`,\n });\n this.permission = permission;\n this.mode = mode;\n }\n}\n","import { ForbiddenException } from '@nestjs/common';\nimport { XltMode } from '@xlt-token/core';\n\nexport class NotRoleException extends ForbiddenException {\n public readonly role: string | string[];\n public readonly mode: XltMode;\n\n constructor(role: string | string[], mode: XltMode) {\n super({\n statusCode: 403,\n type: 'NOT_ROLE',\n message: `缺少角色: ${Array.isArray(role) ? role.join(', ') : role}`,\n });\n this.role = role;\n this.mode = mode;\n }\n}\n","import { ForbiddenException } from \"@nestjs/common\";\n\nexport class NotSafeException extends ForbiddenException {\n readonly business: string;\n\n\n constructor(business: string) {\n super({\n statusCode: 403,\n type: 'NOT_SAFE',\n message: `二级认证未开启:${business}`,\n });\n this.business = business;\n }\n\n}\n","import {\n createExpressContext,\n type CookieOptions,\n type ExpressLikeResponse,\n NotLoginException as CoreNotLoginException,\n NotPermissionException as CoreNotPermissionException,\n NotRoleException as CoreNotRoleException,\n NotSafeException as CoreNotSafeException,\n} from '@xlt-token/core';\nimport { NotLoginException } from '../exceptions/not-login.exception.js';\nimport { NotPermissionException } from '../exceptions/not-permission.exception.js';\nimport { NotRoleException } from '../exceptions/not-role.exception.js';\nimport { NotSafeException } from '../exceptions/not-safe.exception.js';\n\n/**\n * Fastify reply 的写回 API 与 Express response 不同:\n * - 写 header:Express 用 `res.setHeader(n, v)`,Fastify 用 `reply.header(n, v)`\n * - 写 cookie:Express 用 `res.cookie(n, v, o)`,Fastify 用 `reply.setCookie(n, v, o)`\n *\n * 这里把任意一种 response 归一化成 core 期望的 {@link ExpressLikeResponse} 形态,\n * 让核心层无需感知底层 HTTP 平台。读取侧(headers/cookies/query)两个平台形态一致,\n * 直接复用 core 的 createExpressContext。\n */\nfunction normalizeResponse(res: any): ExpressLikeResponse {\n return {\n setHeader(name: string, value: string): void {\n if (typeof res?.setHeader === 'function') {\n // Express response / 原生 Node 响应\n res.setHeader(name, value);\n } else if (typeof res?.header === 'function') {\n // Fastify reply\n res.header(name, value);\n } else {\n throw new Error(\n 'xlt-token: 当前 response 不支持写入 header(既无 setHeader 也无 header 方法)',\n );\n }\n },\n cookie(name: string, value: string, options?: CookieOptions): void {\n if (typeof res?.cookie === 'function') {\n // Express response(或已注册 @fastify/cookie 暴露的 cookie 别名)\n res.cookie(name, value, options);\n } else if (typeof res?.setCookie === 'function') {\n // Fastify reply + @fastify/cookie 插件\n res.setCookie(name, value, options);\n } else {\n throw new Error(\n 'xlt-token: 当前 response 不支持写入 cookie。'\n + '若使用 Fastify,请先注册 @fastify/cookie 插件。',\n );\n }\n },\n };\n}\n\nexport function createNestHttpContext(req: any, res: any) {\n return createExpressContext(req, normalizeResponse(res));\n}\n\nexport function rethrowCoreAuthException(error: unknown): never {\n if (error instanceof CoreNotLoginException) {\n throw new NotLoginException(error.type, error.token);\n }\n if (error instanceof CoreNotPermissionException) {\n throw new NotPermissionException(error.permission, error.mode);\n }\n if (error instanceof CoreNotRoleException) {\n throw new NotRoleException(error.role, error.mode);\n }\n if (error instanceof CoreNotSafeException) {\n throw new NotSafeException(error.business);\n }\n throw error;\n}\n","// 全局守卫\n\nimport { CanActivate, ExecutionContext, Inject, Injectable, Optional } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport {\n type AuthResult,\n StpLogic,\n StpPermLogic,\n XLT_CHECK_LOGIN_KEY,\n XLT_IGNORE_KEY,\n XLT_PERMISSION_KEY,\n XLT_ROLE_KEY,\n XLT_TOKEN_CONFIG,\n type XltTokenConfig,\n} from '@xlt-token/core';\nimport { XLT_CHECK_SAFE_KEY } from '../decorators/xlt-check-safe.decorator.js';\nimport { createNestHttpContext, rethrowCoreAuthException } from '../http/nest-bridge.js';\n\n@Injectable()\nexport class XltTokenGuard implements CanActivate {\n constructor(\n private readonly reflector: Reflector,\n @Inject(XLT_TOKEN_CONFIG) private readonly config: XltTokenConfig,\n private readonly stpLogic: StpLogic,\n @Optional() private readonly stpPermLogic?: StpPermLogic,\n ) {\n }\n\n async canActivate(context: ExecutionContext): Promise<boolean> {\n if (!this.requiresLogin(context)) return true;\n\n const request = context.switchToHttp().getRequest();\n const response = context.switchToHttp().getResponse();\n\n let result: AuthResult;\n try {\n result = await this.stpLogic.checkLogin(createNestHttpContext(request, response));\n } catch (error) {\n rethrowCoreAuthException(error);\n }\n\n const business = this.getBusiness(context);\n request.stpLoginId = result.loginId;\n request.stpToken = result.token;\n\n try {\n if (this.stpPermLogic) {\n const handler = context.getHandler();\n const cls = context.getClass();\n\n const permMeta = this.reflector.getAllAndOverride(XLT_PERMISSION_KEY, [handler, cls]);\n if (permMeta) {\n await this.stpPermLogic.checkPermission(result.loginId!, permMeta.permissions, permMeta.mode);\n }\n\n const roleMeta = this.reflector.getAllAndOverride(XLT_ROLE_KEY, [handler, cls]);\n if (roleMeta) {\n await this.stpPermLogic.checkRole(result.loginId!, roleMeta.roles, roleMeta.mode);\n }\n }\n\n if (business) {\n await this.stpLogic.checkSafe(result.token!, business);\n }\n } catch (error) {\n rethrowCoreAuthException(error);\n }\n\n return true;\n }\n\n private requiresLogin(context: ExecutionContext): boolean {\n const isIgnored = this.reflector.getAllAndOverride<boolean>(XLT_IGNORE_KEY, [\n context.getHandler(),\n context.getClass(),\n ]);\n\n if (this.config.defaultCheck) {\n return !isIgnored;\n }\n\n const shouldCheck = this.reflector.getAllAndOverride<boolean>(XLT_CHECK_LOGIN_KEY, [\n context.getHandler(),\n context.getClass(),\n ]);\n return shouldCheck ?? false;\n }\n\n private getBusiness(context: ExecutionContext): string {\n return this.reflector.getAllAndOverride<string>(XLT_CHECK_SAFE_KEY, [\n context.getHandler(),\n context.getClass(),\n ]);\n }\n}\n","import { CanActivate, ExecutionContext, Inject, Injectable } from '@nestjs/common';\nimport { Reflector } from '@nestjs/core';\nimport {\n NotLoginException as CoreNotLoginException,\n NotLoginType,\n StpLogic,\n XLT_CHECK_LOGIN_KEY,\n XLT_IGNORE_KEY,\n XLT_TOKEN_CONFIG,\n type XltTokenConfig,\n} from '@xlt-token/core';\nimport { NotLoginException } from '../exceptions/not-login.exception.js';\nimport { createNestHttpContext } from '../http/nest-bridge.js';\n\n@Injectable()\nexport abstract class XltAbstractLoginGuard implements CanActivate {\n protected constructor(\n protected readonly reflector: Reflector,\n @Inject(XLT_TOKEN_CONFIG) protected readonly config: XltTokenConfig,\n protected readonly stpLogic: StpLogic,\n ) {}\n\n async canActivate(ctx: ExecutionContext): Promise<boolean> {\n if (!this.requiresLogin(ctx)) return true;\n\n const request = ctx.switchToHttp().getRequest();\n const response = ctx.switchToHttp().getResponse();\n\n let result: { ok: boolean; loginId?: string; token?: string; reason?: NotLoginType };\n try {\n result = await this.stpLogic.checkLogin(createNestHttpContext(request, response));\n } catch (err) {\n if (err instanceof CoreNotLoginException) {\n await this.onAuthFail?.({ ok: false, reason: err.type, token: err.token }, request);\n throw new NotLoginException(err.type, err.token);\n }\n throw err;\n }\n\n request.stpLoginId = result.loginId;\n request.stpToken = result.token;\n await this.onAuthSuccess?.(result, request);\n return true;\n }\n\n protected requiresLogin(ctx: ExecutionContext): boolean {\n const isIgnored = this.reflector.getAllAndOverride<boolean>(XLT_IGNORE_KEY, [ctx.getHandler(), ctx.getClass()]);\n\n if (this.config.defaultCheck) return !isIgnored;\n\n return this.reflector.getAllAndOverride<boolean>(XLT_CHECK_LOGIN_KEY, [ctx.getHandler(), ctx.getClass()]) ?? false;\n }\n\n protected onAuthSuccess?(\n result: {\n ok: boolean;\n loginId?: string | undefined;\n token?: string | undefined;\n reason?: NotLoginType | undefined;\n },\n request: any,\n ): void | Promise<void>;\n\n protected onAuthFail?(\n result: {\n ok: boolean;\n loginId?: string | undefined;\n token?: string | undefined;\n reason?: NotLoginType | undefined;\n },\n request: any,\n ): void | Promise<void>;\n\n protected onPermissionDenied?(\n result: {\n ok: boolean;\n loginId?: string | undefined;\n token?: string | undefined;\n reason?: NotLoginType | undefined;\n },\n request: any,\n ): void | Promise<void>;\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xlt-token/nestjs",
|
|
3
|
-
"version": "1.0.0
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"description": "NestJS integration for xlt-token",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"nestjs",
|
|
@@ -56,12 +56,14 @@
|
|
|
56
56
|
},
|
|
57
57
|
"dependencies": {
|
|
58
58
|
"uuid": "^10.0.0",
|
|
59
|
-
"@xlt-token/core": "1.0.0
|
|
59
|
+
"@xlt-token/core": "1.0.0"
|
|
60
60
|
},
|
|
61
61
|
"devDependencies": {
|
|
62
|
+
"@fastify/cookie": "^9.4.0",
|
|
62
63
|
"@nestjs/common": "^10.0.0",
|
|
63
64
|
"@nestjs/core": "^10.0.0",
|
|
64
65
|
"@nestjs/platform-express": "^10.0.0",
|
|
66
|
+
"@nestjs/platform-fastify": "^10.4.22",
|
|
65
67
|
"@nestjs/testing": "^10.0.0",
|
|
66
68
|
"@swc/core": "^1.15.30",
|
|
67
69
|
"@types/jsonwebtoken": "^9.0.10",
|