import { Controller, Post, Body, Headers, UnauthorizedException } from '@nestjs/common'; import { ApiTags } from '@nestjs/swagger'; import { Throttle } from '@nestjs/throttler'; import { AuthService } from './auth.service'; @ApiTags('auth') @Controller('auth') export class AuthController { constructor(private readonly authService: AuthService) {} /** * حدّ أضيق من العام (docs/17 — D4): كل إرسال ينادي Nabeh (رسالة واتساب * مدفوعة فعلياً) — الحدّ العام (120/دقيقة على كل نقاط API) كان سيسمح * بإغراق مالي رخيص لرقم واحد أو أرقام كثيرة. */ @Throttle({ default: { limit: 3, ttl: 300_000 } }) @Post('send-otp') async sendOtp( @Headers('x-tenant-id') tenantId: string, @Body('phone') phone: string, ) { if (!tenantId) throw new UnauthorizedException('Tenant ID (x-tenant-id) is required'); return this.authService.sendOtp(tenantId, phone); } /** * الحارس الأقوى فعلياً هو عدّاد المحاولات لكل (مستأجر، رقم) داخل * `AuthService` — يصمد أمام تدوير الـIP. هذا الحدّ طبقة إضافية بسيطة على * مستوى الشبكة، لا الحماية الأساسية. */ @Throttle({ default: { limit: 10, ttl: 300_000 } }) @Post('verify-otp') async verifyOtp( @Headers('x-tenant-id') tenantId: string, @Headers('x-device-id') deviceId: string, @Body('phone') phone: string, @Body('code') code: string, ) { if (!tenantId) throw new UnauthorizedException('Tenant ID (x-tenant-id) is required'); return this.authService.verifyOtp(tenantId, phone, code, deviceId); } @Post('refresh') async refresh( @Headers('x-device-id') deviceId: string, @Body('refresh_token') refreshToken: string, ) { if (!refreshToken) throw new UnauthorizedException('refresh_token is required'); return this.authService.refresh(refreshToken, deviceId); } }