From 102b0723a57cd75d37fb63037fee9b8252e5f9e4 Mon Sep 17 00:00:00 2001 From: Innei Date: Sun, 12 Jun 2022 12:39:59 +0800 Subject: [PATCH] fix: jwt verfiy --- patch/bootstrap.js | 2 +- patch/v3.30.0.js | 7 +++++ src/app.config.ts | 5 +++- .../decorator/current-user.decorator.ts | 6 ++++ src/common/guard/auth.guard.ts | 4 +-- src/global/env.global.ts | 5 +--- src/modules/user/user.controller.ts | 12 +++++--- src/processors/helper/helper.jwt.service.ts | 7 +++-- src/utils/tool.util.ts | 28 +++++++++++++++++++ 9 files changed, 62 insertions(+), 14 deletions(-) create mode 100644 patch/v3.30.0.js diff --git a/patch/bootstrap.js b/patch/bootstrap.js index 2693ea88..14eed9cd 100644 --- a/patch/bootstrap.js +++ b/patch/bootstrap.js @@ -9,7 +9,7 @@ Object.assign(global, { isDev: false }) const result = ts.transpileModule( readFileSync(appConfigFile, { encoding: 'utf-8' }), { - compilerOptions: { module: ts.ModuleKind.CommonJS }, + compilerOptions: { module: ts.ModuleKind.CommonJS, esModuleInterop: true }, }, ) const complied = result.outputText diff --git a/patch/v3.30.0.js b/patch/v3.30.0.js new file mode 100644 index 00000000..9b2cdde8 --- /dev/null +++ b/patch/v3.30.0.js @@ -0,0 +1,7 @@ +// patch for version lower than v2.0.0-alpha.1 + +const bootstrap = require('./bootstrap') + +bootstrap(async (db) => { + await db.collection('users').updateMany({}, { $unset: { authCode: 1 } }) +}) diff --git a/src/app.config.ts b/src/app.config.ts index 3f57baa5..758d212c 100644 --- a/src/app.config.ts +++ b/src/app.config.ts @@ -1,7 +1,10 @@ import cluster from 'cluster' import { argv } from 'zx-cjs' -import { cwd, isDev, isTest } from './global/env.global' +export const isDev = process.env.NODE_ENV == 'development' + +export const isTest = !!process.env.TEST +export const cwd = process.cwd() export const PORT = argv.port || process.env.PORT || 2333 export const API_VERSION = 2 diff --git a/src/common/decorator/current-user.decorator.ts b/src/common/decorator/current-user.decorator.ts index 4526408c..1af635fb 100644 --- a/src/common/decorator/current-user.decorator.ts +++ b/src/common/decorator/current-user.decorator.ts @@ -7,3 +7,9 @@ export const CurrentUser = createParamDecorator( return getNestExecutionContextRequest(ctx).user }, ) + +export const CurrentUserToken = createParamDecorator( + (data: unknown, ctx: ExecutionContext) => { + return getNestExecutionContextRequest(ctx).token + }, +) diff --git a/src/common/guard/auth.guard.ts b/src/common/guard/auth.guard.ts index d1ced705..e8080c3d 100644 --- a/src/common/guard/auth.guard.ts +++ b/src/common/guard/auth.guard.ts @@ -35,12 +35,12 @@ export class AuthGuard implements CanActivate { headers.authorization || headers.Authorization || query.token if (!Authorization) { - throw new UnauthorizedException() + throw new UnauthorizedException('未登录') } const jwt = Authorization.replace(/[Bb]earer /, '') const ok = await this.jwtService.verify(jwt) if (!ok) { - throw new UnauthorizedException() + throw new UnauthorizedException('身份过期') } request.user = await this.configs.getMaster() diff --git a/src/global/env.global.ts b/src/global/env.global.ts index fd31b9d7..36f8b35d 100644 --- a/src/global/env.global.ts +++ b/src/global/env.global.ts @@ -1,4 +1 @@ -export const isDev = process.env.NODE_ENV == 'development' - -export const isTest = !!process.env.TEST -export const cwd = process.cwd() +export { isDev, cwd, isTest } from '~/app.config' diff --git a/src/modules/user/user.controller.ts b/src/modules/user/user.controller.ts index 0787d067..68494304 100644 --- a/src/modules/user/user.controller.ts +++ b/src/modules/user/user.controller.ts @@ -3,7 +3,10 @@ import { ApiOperation } from '@nestjs/swagger' import { Auth } from '~/common/decorator/auth.decorator' import { HttpCache } from '~/common/decorator/cache.decorator' -import { CurrentUser } from '~/common/decorator/current-user.decorator' +import { + CurrentUser, + CurrentUserToken, +} from '~/common/decorator/current-user.decorator' import { BanInDemo } from '~/common/decorator/demo.decorator' import { IpLocation, IpRecord } from '~/common/decorator/ip.decorator' import { ApiName } from '~/common/decorator/openapi.decorator' @@ -79,8 +82,9 @@ export class UserController { return await this.userService.patchUserData(user, body) } - @Post('signout') - async singout(@CurrentUser() user: any) { - return this.userService.signout(user.token) + @Post('logout') + @Auth() + async singout(@CurrentUserToken() token: string) { + return this.userService.signout(token) } } diff --git a/src/processors/helper/helper.jwt.service.ts b/src/processors/helper/helper.jwt.service.ts index f976d87c..c4ecbb01 100644 --- a/src/processors/helper/helper.jwt.service.ts +++ b/src/processors/helper/helper.jwt.service.ts @@ -6,7 +6,6 @@ import { Injectable } from '@nestjs/common' import { CLUSTER, SECURITY } from '~/app.config' import { RedisKeys } from '~/constants/cache.constant' -import { isTest } from '~/global/env.global' import { getRedisKey, md5 } from '~/utils' import { CacheService } from '../cache/cache.service' @@ -49,9 +48,13 @@ export class JWTService { } async verify(token: string) { + if (isDev && token == 'dev_token_for_test') { + return true + } + try { verify(token, this.secret) - return isDev && !isTest ? true : await this.isTokenInRedis(token) + return await this.isTokenInRedis(token) } catch (er) { console.debug(er, token) diff --git a/src/utils/tool.util.ts b/src/utils/tool.util.ts index 8ef6670a..5f47a37e 100644 --- a/src/utils/tool.util.ts +++ b/src/utils/tool.util.ts @@ -108,3 +108,31 @@ export const hashString = function (str, seed = 0) { Math.imul(h1 ^ (h1 >>> 13), 3266489909) return 4294967296 * (2097151 & h2) + (h1 >>> 0) } + +export async function* asyncPool( + concurrency: number, + iterable: T[], + iteratorFn: (item: T, arr: T[]) => any, +) { + const executing = new Set>() + async function consume() { + const [promise, value] = await Promise.race(executing) + executing.delete(promise) + return value + } + for (const item of iterable) { + // Wrap iteratorFn() in an async fn to ensure we get a promise. + // Then expose such promise, so it's possible to later reference and + // remove it from the executing pool. + const promise = (async () => await iteratorFn(item, iterable))().then( + (value) => [promise, value], + ) + executing.add(promise) + if (executing.size >= concurrency) { + yield await consume() + } + } + while (executing.size) { + yield await consume() + } +}