import { Body, Controller, Post, HttpCode, HttpStatus } from '@nestjs/common'; import { ApiTags, ApiOperation, ApiResponse, ApiBody } from '@nestjs/swagger'; import { AuthService } from './auth.service'; import { RegisterDto, LoginDto, RequestOtpDto, VerifyOtpDto, RequestPasswordResetDto, ResetPasswordDto } from './auth.dto'; @ApiTags('Auth') @Controller('auth') export class AuthController { constructor(private service: AuthService) {} @Post('register') @ApiOperation({ summary: 'Register new passenger account', description: 'Create a new passenger account with email, phone, and password. Returns user details and JWT token for immediate login.' }) @ApiResponse({ status: 201, description: 'Account created successfully. Returns user object and JWT token.' }) @ApiResponse({ status: 400, description: 'Validation error (invalid email, weak password, etc.)' }) @ApiResponse({ status: 409, description: 'Email or phone already registered' }) @ApiBody({ type: RegisterDto }) register(@Body() dto: RegisterDto) { return this.service.register(dto); } @Post('login') @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Login with email and password', description: 'Authenticate user and receive JWT token. Token expires in 7 days by default. Failed login attempts are tracked and account may be locked after 5 consecutive failures.' }) @ApiResponse({ status: 200, description: 'Login successful. Returns JWT token and user details.' }) @ApiResponse({ status: 401, description: 'Invalid credentials or account locked' }) @ApiResponse({ status: 403, description: 'Account temporarily blocked due to fraud detection' }) @ApiBody({ type: LoginDto }) login(@Body() dto: LoginDto) { return this.service.login(dto); } @Post('otp/request') @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Request OTP verification code', description: 'Send a 6-digit OTP code to user email. Code expires in 10 minutes. Used for registration verification, password reset, or two-factor authentication.' }) @ApiResponse({ status: 200, description: 'OTP sent successfully to email' }) @ApiResponse({ status: 404, description: 'Email not found (for PASSWORD_RESET purpose)' }) @ApiResponse({ status: 429, description: 'Too many OTP requests. Please wait before requesting again.' }) @ApiBody({ type: RequestOtpDto }) requestOtp(@Body() dto: RequestOtpDto) { return this.service.requestOtp(dto); } @Post('otp/verify') @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Verify OTP code', description: 'Validate the 6-digit OTP code sent to user email. Code must match and not be expired.' }) @ApiResponse({ status: 200, description: 'OTP verified successfully' }) @ApiResponse({ status: 400, description: 'Invalid or expired OTP code' }) @ApiResponse({ status: 404, description: 'No OTP found for this email and purpose' }) @ApiBody({ type: VerifyOtpDto }) verifyOtp(@Body() dto: VerifyOtpDto) { return this.service.verifyOtp(dto); } @Post('password/reset-request') @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Request password reset link', description: 'Send password reset link to user email. Link contains a secure token valid for 1 hour.' }) @ApiResponse({ status: 200, description: 'Password reset email sent successfully' }) @ApiResponse({ status: 404, description: 'Email not found' }) @ApiResponse({ status: 429, description: 'Too many reset requests. Please wait before trying again.' }) @ApiBody({ type: RequestPasswordResetDto }) requestPasswordReset(@Body() dto: RequestPasswordResetDto) { return this.service.requestPasswordReset(dto); } @Post('password/reset') @HttpCode(HttpStatus.OK) @ApiOperation({ summary: 'Reset password with token', description: 'Reset user password using the token received via email. Token is single-use and expires after 1 hour.' }) @ApiResponse({ status: 200, description: 'Password reset successfully' }) @ApiResponse({ status: 400, description: 'Invalid, expired, or already used token' }) @ApiResponse({ status: 404, description: 'User not found' }) @ApiBody({ type: ResetPasswordDto }) resetPassword(@Body() dto: ResetPasswordDto) { return this.service.resetPassword(dto); } }