fix: fix some changes

This commit is contained in:
2026-10-05 17:27:37 +03:30
parent 5c4e9df341
commit f3fe1f55e4
7 changed files with 113 additions and 2 deletions
+2 -1
View File
@@ -14,6 +14,7 @@
},
"messages": {
"otpSent": "OTP sent to {phone}.",
"sendPass": "Please send password."
"sendPass": "Please send password.",
"loggedOut": "Logged out successfully."
}
}
+2 -1
View File
@@ -14,6 +14,7 @@
},
"messages": {
"otpSent": "کد تایید به شماره {phone} ارسال شد.",
"sendPass": "لطفا رمز عبور را ارسال کنید."
"sendPass": "لطفا رمز عبور را ارسال کنید.",
"loggedOut": "با موفقیت خارج شدید."
}
}
+27
View File
@@ -9,6 +9,9 @@ import { ApiAppResponse } from '@/common/decorators/api-app-response.decorator';
import { NewUserLoginResponseDTO } from './dtos/responses/new-user-login.dto';
import { RequirePasswordDTO } from './dtos/responses/require-password.dto';
import { TokensResponseDTO } from './dtos/responses/tokens.dto';
import { LogoutDTO } from './dtos/logout.dto';
import { ActiveUser } from '@/common/decorators/active-user.decorator';
import { User } from '@/modules/users/entities/user.entity';
@Controller('auth')
export class AuthController {
@@ -126,4 +129,28 @@ export class AuthController {
public async refreshToken(@Body() refreshTokenDto: RefreshTokenDTO) {
return await this.authService.refreshToken(refreshTokenDto);
}
@Post('logout')
@HttpCode(HttpStatus.OK)
@ApiAppResponse([
{
status: HttpStatus.OK,
variants: [
{
messageExample: 'با موفقیت خارج شدید.',
},
],
},
{
status: HttpStatus.UNAUTHORIZED,
variants: [
{
messageExample: 'دسترسی غیر مجاز',
},
],
},
])
public async logout(@ActiveUser() user: User, @Body() logoutDto: LogoutDTO) {
return await this.authService.logout(user.id, logoutDto);
}
}
+2
View File
@@ -15,6 +15,7 @@ import { GlobalAuthGuard } from './guards/global-auth.guard';
import { RefreshTokensProvider } from './providers/refresh-tokens.provider';
import { RedisModule } from '@/common/modules/redis/redis.module';
import { AuthRedisProvider } from './providers/auth-redis.provider';
import { LogoutProvider } from './providers/logout.provider';
@Module({
imports: [
@@ -43,6 +44,7 @@ import { AuthRedisProvider } from './providers/auth-redis.provider';
JwtStrategy,
RefreshTokensProvider,
AuthRedisProvider,
LogoutProvider,
{
provide: APP_GUARD,
useClass: GlobalAuthGuard,
+13
View File
@@ -0,0 +1,13 @@
import { ApiProperty } from '@nestjs/swagger';
import { IsNotEmpty, IsString } from 'class-validator';
export class LogoutDTO {
@IsNotEmpty()
@IsString()
@ApiProperty({
type: 'string',
description: "User's Refresh Token",
required: true,
})
refreshToken!: string;
}
@@ -5,6 +5,8 @@ import { VerifyOtpDTO } from '../dtos/verify-otp.dto';
import { VerifyOTPProvider } from './verify-otp.provider';
import { RefreshTokenDTO } from '../dtos/refresh-token.dto';
import { RefreshTokensProvider } from './refresh-tokens.provider';
import { LogoutDTO } from '../dtos/logout.dto';
import { LogoutProvider } from './logout.provider';
@Injectable()
export class AuthService {
@@ -23,6 +25,11 @@ export class AuthService {
* Inject RefreshToken Provider
*/
private readonly refreshTokensProvider: RefreshTokensProvider,
/**
* Inject Logout Provider
*/
private readonly logoutProvider: LogoutProvider,
) {}
public async logIn(loginDto: LoginDTO) {
@@ -36,4 +43,8 @@ export class AuthService {
public async refreshToken(refreshTokenDto: RefreshTokenDTO) {
return await this.refreshTokensProvider.refreshTokens(refreshTokenDto);
}
public async logout(userId: number, logoutDto: LogoutDTO) {
return await this.logoutProvider.logout(userId, logoutDto);
}
}
@@ -0,0 +1,56 @@
import { Inject, Injectable, UnauthorizedException } from '@nestjs/common';
import { JwtService } from '@nestjs/jwt';
import type { ConfigType } from '@nestjs/config';
import jwtConfig from '@/config/jwt.config';
import { RefreshTokenPayload } from '../interfaces/jwt.interface';
import { AuthRedisProvider } from './auth-redis.provider';
import { LogoutDTO } from '../dtos/logout.dto';
import { AppResponse } from '@/common/responses';
import { I18nService } from 'nestjs-i18n';
@Injectable()
export class LogoutProvider {
constructor(
/**
* Inject JwtService
*/
private readonly jwtService: JwtService,
/**
* Inject jwtConfig
*/
@Inject(jwtConfig.KEY)
private readonly jwtConfiguration: ConfigType<typeof jwtConfig>,
/**
* Inject AuthRedis Provider
*/
private readonly authRedisProvider: AuthRedisProvider,
/**
* Inject I18n Service
*/
private readonly i18nService: I18nService,
) {}
public async logout(userId: number, logoutDto: LogoutDTO) {
const payload = await this.jwtService.verifyAsync<RefreshTokenPayload>(
logoutDto.refreshToken,
{
secret: this.jwtConfiguration.refresh.secret,
issuer: this.jwtConfiguration.issuer,
audience: this.jwtConfiguration.audience,
},
);
if (payload.sub !== userId || !payload.jti) {
throw new UnauthorizedException('auth.errors.unauthorized');
}
await this.authRedisProvider.revokeRefreshToken(payload.jti);
const message = this.i18nService.translate('auth.messages.loggedOut');
return new AppResponse(null, message);
}
}