From 2de08b9e65d7c4b736c4bfdd2d7ea96947ac4cc9 Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Mon, 24 Nov 2025 18:39:57 +0330 Subject: [PATCH] fix bugs --- src/app.module.ts | 22 ++++++++-------- src/modules/auth/auth.module.ts | 6 ++--- .../auth/controllers/admin-auth.controller.ts | 3 +-- .../auth/controllers/auth.controller.ts | 4 +-- src/modules/auth/guards/auth.guard.ts | 13 ++++++---- src/modules/auth/services/auth.service.ts | 4 +-- src/modules/auth/services/tokens.service.ts | 25 +++++++++++++------ 7 files changed, 44 insertions(+), 33 deletions(-) diff --git a/src/app.module.ts b/src/app.module.ts index 0d957f2..ba5f23d 100644 --- a/src/app.module.ts +++ b/src/app.module.ts @@ -9,7 +9,7 @@ import { UtilsModule } from './modules/utils/utils.module'; // import { HttpModule } from '@nestjs/axios'; // import { httpConfig } from './config/http.config'; import { AuthModule } from './modules/auth/auth.module'; -import { JwtModule } from '@nestjs/jwt'; +// import { JwtModule } from '@nestjs/jwt'; import { UploaderModule } from './modules/uploader/uploader.module'; import { AdminModule } from './modules/admin/admin.module'; // import { CacheService } from './modules/utils/cache.service'; @@ -26,16 +26,16 @@ import { ShipmentsModule } from './modules/shipments/shipments.module'; ConfigModule.forRoot({ isGlobal: true, cache: true }), MikroOrmModule.forRootAsync(dataBaseConfig), // CacheModule.registerAsync(cacheConfig()), - JwtModule.registerAsync({ - useFactory: (configService: ConfigService) => ({ - global: true, - secret: configService.getOrThrow('JWT_SECRET'), - signOptions: { - expiresIn: configService.getOrThrow('JWT_EXPIRATION_TIME'), - }, - }), - inject: [ConfigService], - }), + // JwtModule.registerAsync({ + // useFactory: (configService: ConfigService) => ({ + // global: true, + // secret: configService.getOrThrow('JWT_SECRET'), + // // signOptions: { + // // expiresIn: configService.getOrThrow('JWT_EXPIRATION_TIME'), + // // }, + // }), + // inject: [ConfigService], + // }), UserModule, UtilsModule, AuthModule, diff --git a/src/modules/auth/auth.module.ts b/src/modules/auth/auth.module.ts index 78b160b..0aa9f21 100644 --- a/src/modules/auth/auth.module.ts +++ b/src/modules/auth/auth.module.ts @@ -22,9 +22,9 @@ import { RefreshToken } from './entities/refresh-token.entity'; useFactory: (configService: ConfigService) => ({ global: true, secret: configService.getOrThrow('JWT_SECRET'), - signOptions: { - expiresIn: configService.getOrThrow('JWT_EXPIRATION_TIME'), - }, + // signOptions: { + // expiresIn: configService.getOrThrow('JWT_EXPIRATION_TIME'), + // }, }), inject: [ConfigService], }), diff --git a/src/modules/auth/controllers/admin-auth.controller.ts b/src/modules/auth/controllers/admin-auth.controller.ts index cff64b6..5f2ad65 100644 --- a/src/modules/auth/controllers/admin-auth.controller.ts +++ b/src/modules/auth/controllers/admin-auth.controller.ts @@ -31,11 +31,10 @@ export class AdminAuthController { return this.authService.verifyOtpAdmin(dto.phone, dto.slug, dto.otp); // assuming dto has `otp` property } - @RefreshTokenRateLimit() @ApiOperation({ summary: 'refresh the admin access token / refresh token' }) @Post('refresh') refreshToken(@Body() refreshTokenDto: RefreshTokenDto) { - return this.authService.refreshToken(refreshTokenDto.refreshToken, true); + return this.authService.refreshToken(refreshTokenDto.refreshToken); } } diff --git a/src/modules/auth/controllers/auth.controller.ts b/src/modules/auth/controllers/auth.controller.ts index 8300834..c294097 100644 --- a/src/modules/auth/controllers/auth.controller.ts +++ b/src/modules/auth/controllers/auth.controller.ts @@ -31,12 +31,10 @@ export class AuthController { return this.authService.verifyOtp(dto.phone, dto.slug, dto.otp); // assuming dto has `otp` property } - - @RefreshTokenRateLimit() @ApiOperation({ summary: 'refresh the user access token / refresh token' }) @Post('refresh') refreshToken(@Body() refreshTokenDto: RefreshTokenDto) { - return this.authService.refreshToken(refreshTokenDto.refreshToken, false); + return this.authService.refreshToken(refreshTokenDto.refreshToken); } } diff --git a/src/modules/auth/guards/auth.guard.ts b/src/modules/auth/guards/auth.guard.ts index 0878d4d..884f07d 100644 --- a/src/modules/auth/guards/auth.guard.ts +++ b/src/modules/auth/guards/auth.guard.ts @@ -4,8 +4,8 @@ import { JwtService } from '@nestjs/jwt'; import { ConfigService } from '@nestjs/config'; import { ITokenPayload } from '../interfaces/IToken-payload'; -export interface AdminAuthRequest extends Request { - adminId: string; +export interface UserAuthRequest extends Request { + userId: string; restId: string; } @@ -21,10 +21,10 @@ export class AuthGuard implements CanActivate { ) {} async canActivate(context: ExecutionContext) { - const request = context.switchToHttp().getRequest(); + const request = context.switchToHttp().getRequest(); try { - const secret = this.configService.get('JWT_SECRET'); + const secret = this.configService.getOrThrow('JWT_SECRET'); const token = this.extractTokenFromHeader(request); if (!token) { throw new UnauthorizedException(); @@ -46,7 +46,10 @@ export class AuthGuard implements CanActivate { return true; } catch (err) { - console.log('error in AuthGuard', err); + if (err instanceof UnauthorizedException) { + throw err; + } + this.logger.error('error in AuthGuard', err); throw new UnauthorizedException('Invalid or expired token'); } } diff --git a/src/modules/auth/services/auth.service.ts b/src/modules/auth/services/auth.service.ts index f9f80ba..196f0bf 100644 --- a/src/modules/auth/services/auth.service.ts +++ b/src/modules/auth/services/auth.service.ts @@ -101,7 +101,7 @@ export class AuthService { return code.toString(); } - refreshToken(oldRefreshToken: string, isAdmin: boolean) { - return this.tokensService.refreshToken(oldRefreshToken, isAdmin); + refreshToken(oldRefreshToken: string) { + return this.tokensService.refreshToken(oldRefreshToken); } } diff --git a/src/modules/auth/services/tokens.service.ts b/src/modules/auth/services/tokens.service.ts index c283e8f..0ffe9cc 100755 --- a/src/modules/auth/services/tokens.service.ts +++ b/src/modules/auth/services/tokens.service.ts @@ -57,7 +57,7 @@ export class TokensService { return this.em.persistAndFlush(token); } - async refreshToken(oldRefreshToken: string, isAdmin: boolean) { + async refreshToken(oldRefreshToken: string) { const token = await this.em.findOne(RefreshToken, { token: oldRefreshToken }); if (!token) throw new UnauthorizedException(AuthMessage.INVALID_REFRESH_TOKEN); @@ -68,16 +68,27 @@ export class TokensService { throw new UnauthorizedException(AuthMessage.REFRESH_TOKEN_EXPIRED); } + // Store token data before removal + const ownerId = token.ownerId; + const restId = token.restId; + // Remove the old token this.em.remove(token); + const isAdmin = token.type === RefreshTokenType.ADMIN; + try { + // Generate new tokens + const tokens = await this.generateAccessAndRefreshToken(ownerId, restId, isAdmin); - // Generate new tokens within the same transaction - const tokens = await this.generateAccessAndRefreshToken(token.ownerId, token.restId, isAdmin); + // Commit the transaction + await this.em.flush(); - // Commit the transaction - await this.em.flush(); - - return tokens; + return tokens; + } catch (error) { + // If token generation fails, the old token is already removed + // This is acceptable as the token was already used + this.logger.error('Failed to generate new tokens after refresh', error); + throw new UnauthorizedException('Failed to refresh token'); + } } private generateRefreshToken() {