fix bugs
This commit is contained in:
+11
-11
@@ -9,7 +9,7 @@ import { UtilsModule } from './modules/utils/utils.module';
|
|||||||
// import { HttpModule } from '@nestjs/axios';
|
// import { HttpModule } from '@nestjs/axios';
|
||||||
// import { httpConfig } from './config/http.config';
|
// import { httpConfig } from './config/http.config';
|
||||||
import { AuthModule } from './modules/auth/auth.module';
|
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 { UploaderModule } from './modules/uploader/uploader.module';
|
||||||
import { AdminModule } from './modules/admin/admin.module';
|
import { AdminModule } from './modules/admin/admin.module';
|
||||||
// import { CacheService } from './modules/utils/cache.service';
|
// import { CacheService } from './modules/utils/cache.service';
|
||||||
@@ -26,16 +26,16 @@ import { ShipmentsModule } from './modules/shipments/shipments.module';
|
|||||||
ConfigModule.forRoot({ isGlobal: true, cache: true }),
|
ConfigModule.forRoot({ isGlobal: true, cache: true }),
|
||||||
MikroOrmModule.forRootAsync(dataBaseConfig),
|
MikroOrmModule.forRootAsync(dataBaseConfig),
|
||||||
// CacheModule.registerAsync(cacheConfig()),
|
// CacheModule.registerAsync(cacheConfig()),
|
||||||
JwtModule.registerAsync({
|
// JwtModule.registerAsync({
|
||||||
useFactory: (configService: ConfigService) => ({
|
// useFactory: (configService: ConfigService) => ({
|
||||||
global: true,
|
// global: true,
|
||||||
secret: configService.getOrThrow<string>('JWT_SECRET'),
|
// secret: configService.getOrThrow<string>('JWT_SECRET'),
|
||||||
signOptions: {
|
// // signOptions: {
|
||||||
expiresIn: configService.getOrThrow<number>('JWT_EXPIRATION_TIME'),
|
// // expiresIn: configService.getOrThrow<number>('JWT_EXPIRATION_TIME'),
|
||||||
},
|
// // },
|
||||||
}),
|
// }),
|
||||||
inject: [ConfigService],
|
// inject: [ConfigService],
|
||||||
}),
|
// }),
|
||||||
UserModule,
|
UserModule,
|
||||||
UtilsModule,
|
UtilsModule,
|
||||||
AuthModule,
|
AuthModule,
|
||||||
|
|||||||
@@ -22,9 +22,9 @@ import { RefreshToken } from './entities/refresh-token.entity';
|
|||||||
useFactory: (configService: ConfigService) => ({
|
useFactory: (configService: ConfigService) => ({
|
||||||
global: true,
|
global: true,
|
||||||
secret: configService.getOrThrow<string>('JWT_SECRET'),
|
secret: configService.getOrThrow<string>('JWT_SECRET'),
|
||||||
signOptions: {
|
// signOptions: {
|
||||||
expiresIn: configService.getOrThrow<number>('JWT_EXPIRATION_TIME'),
|
// expiresIn: configService.getOrThrow<number>('JWT_EXPIRATION_TIME'),
|
||||||
},
|
// },
|
||||||
}),
|
}),
|
||||||
inject: [ConfigService],
|
inject: [ConfigService],
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -31,11 +31,10 @@ export class AdminAuthController {
|
|||||||
return this.authService.verifyOtpAdmin(dto.phone, dto.slug, dto.otp); // assuming dto has `otp` property
|
return this.authService.verifyOtpAdmin(dto.phone, dto.slug, dto.otp); // assuming dto has `otp` property
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@RefreshTokenRateLimit()
|
@RefreshTokenRateLimit()
|
||||||
@ApiOperation({ summary: 'refresh the admin access token / refresh token' })
|
@ApiOperation({ summary: 'refresh the admin access token / refresh token' })
|
||||||
@Post('refresh')
|
@Post('refresh')
|
||||||
refreshToken(@Body() refreshTokenDto: RefreshTokenDto) {
|
refreshToken(@Body() refreshTokenDto: RefreshTokenDto) {
|
||||||
return this.authService.refreshToken(refreshTokenDto.refreshToken, true);
|
return this.authService.refreshToken(refreshTokenDto.refreshToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,12 +31,10 @@ export class AuthController {
|
|||||||
return this.authService.verifyOtp(dto.phone, dto.slug, dto.otp); // assuming dto has `otp` property
|
return this.authService.verifyOtp(dto.phone, dto.slug, dto.otp); // assuming dto has `otp` property
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@RefreshTokenRateLimit()
|
@RefreshTokenRateLimit()
|
||||||
@ApiOperation({ summary: 'refresh the user access token / refresh token' })
|
@ApiOperation({ summary: 'refresh the user access token / refresh token' })
|
||||||
@Post('refresh')
|
@Post('refresh')
|
||||||
refreshToken(@Body() refreshTokenDto: RefreshTokenDto) {
|
refreshToken(@Body() refreshTokenDto: RefreshTokenDto) {
|
||||||
return this.authService.refreshToken(refreshTokenDto.refreshToken, false);
|
return this.authService.refreshToken(refreshTokenDto.refreshToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import { JwtService } from '@nestjs/jwt';
|
|||||||
import { ConfigService } from '@nestjs/config';
|
import { ConfigService } from '@nestjs/config';
|
||||||
import { ITokenPayload } from '../interfaces/IToken-payload';
|
import { ITokenPayload } from '../interfaces/IToken-payload';
|
||||||
|
|
||||||
export interface AdminAuthRequest extends Request {
|
export interface UserAuthRequest extends Request {
|
||||||
adminId: string;
|
userId: string;
|
||||||
restId: string;
|
restId: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -21,10 +21,10 @@ export class AuthGuard implements CanActivate {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
async canActivate(context: ExecutionContext) {
|
async canActivate(context: ExecutionContext) {
|
||||||
const request = context.switchToHttp().getRequest<AdminAuthRequest>();
|
const request = context.switchToHttp().getRequest<UserAuthRequest>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const secret = this.configService.get<string>('JWT_SECRET');
|
const secret = this.configService.getOrThrow<string>('JWT_SECRET');
|
||||||
const token = this.extractTokenFromHeader(request);
|
const token = this.extractTokenFromHeader(request);
|
||||||
if (!token) {
|
if (!token) {
|
||||||
throw new UnauthorizedException();
|
throw new UnauthorizedException();
|
||||||
@@ -46,7 +46,10 @@ export class AuthGuard implements CanActivate {
|
|||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} 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');
|
throw new UnauthorizedException('Invalid or expired token');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -101,7 +101,7 @@ export class AuthService {
|
|||||||
return code.toString();
|
return code.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshToken(oldRefreshToken: string, isAdmin: boolean) {
|
refreshToken(oldRefreshToken: string) {
|
||||||
return this.tokensService.refreshToken(oldRefreshToken, isAdmin);
|
return this.tokensService.refreshToken(oldRefreshToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ export class TokensService {
|
|||||||
return this.em.persistAndFlush(token);
|
return this.em.persistAndFlush(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
async refreshToken(oldRefreshToken: string, isAdmin: boolean) {
|
async refreshToken(oldRefreshToken: string) {
|
||||||
const token = await this.em.findOne(RefreshToken, { token: oldRefreshToken });
|
const token = await this.em.findOne(RefreshToken, { token: oldRefreshToken });
|
||||||
|
|
||||||
if (!token) throw new UnauthorizedException(AuthMessage.INVALID_REFRESH_TOKEN);
|
if (!token) throw new UnauthorizedException(AuthMessage.INVALID_REFRESH_TOKEN);
|
||||||
@@ -68,16 +68,27 @@ export class TokensService {
|
|||||||
throw new UnauthorizedException(AuthMessage.REFRESH_TOKEN_EXPIRED);
|
throw new UnauthorizedException(AuthMessage.REFRESH_TOKEN_EXPIRED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Store token data before removal
|
||||||
|
const ownerId = token.ownerId;
|
||||||
|
const restId = token.restId;
|
||||||
|
|
||||||
// Remove the old token
|
// Remove the old token
|
||||||
this.em.remove(token);
|
this.em.remove(token);
|
||||||
|
const isAdmin = token.type === RefreshTokenType.ADMIN;
|
||||||
// Generate new tokens within the same transaction
|
try {
|
||||||
const tokens = await this.generateAccessAndRefreshToken(token.ownerId, token.restId, isAdmin);
|
// Generate new tokens
|
||||||
|
const tokens = await this.generateAccessAndRefreshToken(ownerId, restId, isAdmin);
|
||||||
|
|
||||||
// Commit the transaction
|
// Commit the transaction
|
||||||
await this.em.flush();
|
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() {
|
private generateRefreshToken() {
|
||||||
|
|||||||
Reference in New Issue
Block a user