update: remove the auth guard from the feedback route

This commit is contained in:
mahyargdz
2025-08-20 09:26:43 +03:30
parent aa487809ee
commit 7b6b79dfa8
6 changed files with 41 additions and 12 deletions
@@ -0,0 +1,11 @@
import { UseGuards, applyDecorators } from "@nestjs/common";
import { Throttle, ThrottlerGuard } from "@nestjs/throttler";
import { AUTH_THROTTLE_LIMIT, AUTH_THROTTLE_TTL, AUTH__REFRESH_THROTTLE_LIMIT, AUTH__REFRESH_THROTTLE_TTL } from "../constants";
export const RateLimit = (limit: number, ttl: number) => applyDecorators(Throttle({ default: { limit, ttl } }), UseGuards(ThrottlerGuard));
export const StrictRateLimit = () => RateLimit(AUTH_THROTTLE_LIMIT, AUTH_THROTTLE_TTL); // 5 requests per minute
export const StandardRateLimit = () => RateLimit(20, 60000); // 20 requests per minute
export const MailSendRateLimit = () => RateLimit(10, 60000); // 10 emails per minute
export const RefreshTokenRateLimit = () => RateLimit(AUTH__REFRESH_THROTTLE_LIMIT, AUTH__REFRESH_THROTTLE_TTL); // 10 refresh tokens per minute
+5 -7
View File
@@ -1,25 +1,23 @@
import { Body, Controller, HttpCode, HttpStatus, Patch, Post, UseGuards } from "@nestjs/common"; import { Body, Controller, HttpCode, HttpStatus, Patch, Post } from "@nestjs/common";
import { ApiOperation, ApiTags } from "@nestjs/swagger"; import { ApiOperation, ApiTags } from "@nestjs/swagger";
import { Throttle, ThrottlerGuard } from "@nestjs/throttler";
import { ChangePasswordDto } from "./DTO/change-password.dto"; import { ChangePasswordDto } from "./DTO/change-password.dto";
import { CheckUserExistDto, LoginPasswordDTO } from "./DTO/loginPassword.dto"; import { CheckUserExistDto, LoginPasswordDTO } from "./DTO/loginPassword.dto";
import { RefreshTokenDto } from "./DTO/refresh-token.dto"; import { RefreshTokenDto } from "./DTO/refresh-token.dto";
import { RequestOtpDto } from "./DTO/request-otp.dto"; import { RequestOtpDto } from "./DTO/request-otp.dto";
import { SSOTokenRequestDTO } from "./DTO/requests/sso-token-request.dto"; import { SSOTokenRequestDTO } from "./DTO/requests/sso-token-request.dto";
import { SSOTokenValidateDTO } from "./DTO/requests/sso-token-validate.dto";
import { VerifyOtpDto } from "./DTO/verify-otp.dto"; import { VerifyOtpDto } from "./DTO/verify-otp.dto";
import { AuthService } from "./providers/auth.service"; import { AuthService } from "./providers/auth.service";
import { SSOService } from "./providers/sso.service"; import { SSOService } from "./providers/sso.service";
import { AUTH_THROTTLE_LIMIT, AUTH_THROTTLE_TTL, AUTH__REFRESH_THROTTLE_LIMIT, AUTH__REFRESH_THROTTLE_TTL } from "../../common/constants";
import { SSOTokenValidateDTO } from "./DTO/requests/sso-token-validate.dto";
import { AuthGuards } from "../../common/decorators/auth-guard.decorator"; import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
import { RefreshTokenRateLimit, StrictRateLimit } from "../../common/decorators/rate-limit.decorator";
import { UserDec } from "../../common/decorators/user.decorator"; import { UserDec } from "../../common/decorators/user.decorator";
import { User } from "../users/entities/user.entity"; import { User } from "../users/entities/user.entity";
@ApiTags("Auth") @ApiTags("Auth")
@Controller("auth") @Controller("auth")
@Throttle({ default: { limit: AUTH_THROTTLE_LIMIT, ttl: AUTH_THROTTLE_TTL } }) @StrictRateLimit()
@UseGuards(ThrottlerGuard)
export class AuthController { export class AuthController {
constructor( constructor(
private readonly authService: AuthService, private readonly authService: AuthService,
@@ -77,7 +75,7 @@ export class AuthController {
return this.authService.changePassword(userId, changePasswordDto); return this.authService.changePassword(userId, changePasswordDto);
} }
@Throttle({ default: { limit: AUTH__REFRESH_THROTTLE_LIMIT, ttl: AUTH__REFRESH_THROTTLE_TTL } }) @RefreshTokenRateLimit()
@ApiOperation({ summary: "refresh the user access token / refresh token" }) @ApiOperation({ summary: "refresh the user access token / refresh token" })
@HttpCode(HttpStatus.OK) @HttpCode(HttpStatus.OK)
@Post("refresh") @Post("refresh")
@@ -1,7 +1,7 @@
import { ApiProperty } from "@nestjs/swagger"; import { ApiProperty } from "@nestjs/swagger";
import { IsIn, IsInt, IsNotEmpty, IsString, IsUUID, Length } from "class-validator"; import { IsEmail, IsIn, IsInt, IsMobilePhone, IsNotEmpty, IsOptional, IsString, IsUUID, Length } from "class-validator";
import { ServiceMessage, UserMessage } from "../../../common/enums/message.enum"; import { AuthMessage, ServiceMessage, UserMessage } from "../../../common/enums/message.enum";
export class CreateServiceFeedbackDto { export class CreateServiceFeedbackDto {
@IsNotEmpty({ message: ServiceMessage.COMMENT_REQUIRED }) @IsNotEmpty({ message: ServiceMessage.COMMENT_REQUIRED })
@@ -21,8 +21,21 @@ export class CreateServiceFeedbackDto {
@ApiProperty({ description: "Service ID", example: "d290f1ee-6c54-4b01-90e6-d701748f0851" }) @ApiProperty({ description: "Service ID", example: "d290f1ee-6c54-4b01-90e6-d701748f0851" })
serviceId: string; serviceId: string;
@IsOptional()
@IsNotEmpty({ message: UserMessage.USER_ID_REQUIRED }) @IsNotEmpty({ message: UserMessage.USER_ID_REQUIRED })
@IsUUID("all", { message: UserMessage.USER_ID_SHOULD_BE_A_UUID }) @IsUUID("all", { message: UserMessage.USER_ID_SHOULD_BE_A_UUID })
@ApiProperty({ description: "User ID", example: "d290f1ee-6c54-4b01-90e6-d701748f0851" }) @ApiProperty({ description: "User ID", example: "d290f1ee-6c54-4b01-90e6-d701748f0851" })
userId: string; userId?: string;
@IsOptional()
@IsNotEmpty({ message: AuthMessage.PHONE_NOT_EMPTY })
@IsMobilePhone("fa-IR", {}, { message: AuthMessage.INVALID_PHONE_FORMAT })
@ApiProperty({ description: "User Phone", example: "+989123456789" })
phone?: string;
@IsOptional()
@IsNotEmpty({ message: AuthMessage.EMAIL_NOT_EMPTY })
@IsEmail({}, { message: AuthMessage.INVALID_EMAIL_FORMAT })
@ApiProperty({ description: "User Email", example: "example@example.com" })
email: string;
} }
@@ -20,6 +20,7 @@ import { DanakServicesService } from "./providers/danak-services.service";
import { AuthGuards } from "../../common/decorators/auth-guard.decorator"; import { AuthGuards } from "../../common/decorators/auth-guard.decorator";
import { Pagination } from "../../common/decorators/pagination.decorator"; import { Pagination } from "../../common/decorators/pagination.decorator";
import { PermissionsDec } from "../../common/decorators/permission.decorator"; import { PermissionsDec } from "../../common/decorators/permission.decorator";
import { StrictRateLimit } from "../../common/decorators/rate-limit.decorator";
import { UserDec } from "../../common/decorators/user.decorator"; import { UserDec } from "../../common/decorators/user.decorator";
import { ParamDto } from "../../common/DTO/param.dto"; import { ParamDto } from "../../common/DTO/param.dto";
import { PermissionEnum } from "../users/enums/permission.enum"; import { PermissionEnum } from "../users/enums/permission.enum";
@@ -270,7 +271,7 @@ export class DanakServicesController {
//------------------------ service feedback ------------------------ //------------------------ service feedback ------------------------
@ApiOperation({ summary: "Create service feedback => user route" }) @ApiOperation({ summary: "Create service feedback => user route" })
@AuthGuards() @StrictRateLimit()
@Post("feedback") @Post("feedback")
createServiceFeedback(@Body() createDto: CreateServiceFeedbackDto, @Headers() headers: Record<string, string>, @Ip() ip: string) { createServiceFeedback(@Body() createDto: CreateServiceFeedbackDto, @Headers() headers: Record<string, string>, @Ip() ip: string) {
return this.danakServicesService.createServiceFeedback(createDto, headers, ip); return this.danakServicesService.createServiceFeedback(createDto, headers, ip);
@@ -18,6 +18,12 @@ export class DanakServiceFeedback extends BaseEntity {
@ManyToOne(() => User, (user) => user.serviceFeedbacks, { onDelete: "SET NULL", nullable: true }) @ManyToOne(() => User, (user) => user.serviceFeedbacks, { onDelete: "SET NULL", nullable: true })
user: User | null; user: User | null;
@Column({ type: "varchar", nullable: true })
phone: string | null;
@Column({ type: "varchar", nullable: true })
email: string | null;
@ManyToOne(() => DanakService, (service) => service.feedbacks, { onDelete: "CASCADE", nullable: false }) @ManyToOne(() => DanakService, (service) => service.feedbacks, { onDelete: "CASCADE", nullable: false })
service: DanakService; service: DanakService;
+1 -1
View File
@@ -249,7 +249,7 @@ export class UsersService {
const userName = slugify(`u-${registerDto.phone}`, { lower: true, trim: true }); const userName = slugify(`u-${registerDto.phone}`, { lower: true, trim: true });
const defaultFirstName = "کاربر"; const defaultFirstName = "کاربر";
const defaultLastName = userName.slice(0, 5); const defaultLastName = userName;
const { referralCode, ...userData } = registerDto; const { referralCode, ...userData } = registerDto;
const user = queryRunner.manager.create(User, { const user = queryRunner.manager.create(User, {