xpeditis2.0/apps/backend/src/application/controllers/carrier-auth.controller.ts
2025-12-05 13:55:40 +01:00

153 lines
4.7 KiB
TypeScript

/**
* Carrier Auth Controller
*
* Handles carrier authentication endpoints
*/
import {
Controller,
Post,
Body,
HttpCode,
HttpStatus,
UseGuards,
Request,
Get,
Patch,
Logger,
} from '@nestjs/common';
import { ApiTags, ApiOperation, ApiResponse, ApiBearerAuth } from '@nestjs/swagger';
import { CarrierAuthService } from '../services/carrier-auth.service';
import { Public } from '../decorators/public.decorator';
import { JwtAuthGuard } from '../guards/jwt-auth.guard';
import {
CarrierLoginDto,
CarrierChangePasswordDto,
CarrierPasswordResetRequestDto,
CarrierLoginResponseDto,
CarrierProfileResponseDto,
} from '../dto/carrier-auth.dto';
import { CarrierProfileRepository } from '@infrastructure/persistence/typeorm/repositories/carrier-profile.repository';
@ApiTags('Carrier Auth')
@Controller('carrier-auth')
export class CarrierAuthController {
private readonly logger = new Logger(CarrierAuthController.name);
constructor(
private readonly carrierAuthService: CarrierAuthService,
private readonly carrierProfileRepository: CarrierProfileRepository,
) {}
@Public()
@Post('login')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'Carrier login with email and password' })
@ApiResponse({
status: 200,
description: 'Login successful',
type: CarrierLoginResponseDto,
})
@ApiResponse({ status: 401, description: 'Invalid credentials' })
async login(@Body() dto: CarrierLoginDto): Promise<CarrierLoginResponseDto> {
this.logger.log(`Carrier login attempt: ${dto.email}`);
return await this.carrierAuthService.login(dto.email, dto.password);
}
@UseGuards(JwtAuthGuard)
@Get('me')
@ApiBearerAuth()
@ApiOperation({ summary: 'Get current carrier profile' })
@ApiResponse({
status: 200,
description: 'Profile retrieved',
type: CarrierProfileResponseDto,
})
@ApiResponse({ status: 401, description: 'Unauthorized' })
async getProfile(@Request() req: any): Promise<any> {
this.logger.log(`Getting profile for carrier: ${req.user.carrierId}`);
const carrier = await this.carrierProfileRepository.findById(req.user.carrierId);
if (!carrier) {
throw new Error('Carrier profile not found');
}
return {
id: carrier.id,
userId: carrier.userId,
companyName: carrier.companyName,
email: carrier.user?.email,
role: 'CARRIER',
organizationId: carrier.organizationId,
phone: carrier.phone,
website: carrier.website,
city: carrier.city,
country: carrier.country,
isVerified: carrier.isVerified,
isActive: carrier.isActive,
totalBookingsAccepted: carrier.totalBookingsAccepted,
totalBookingsRejected: carrier.totalBookingsRejected,
acceptanceRate: carrier.acceptanceRate,
totalRevenueUsd: carrier.totalRevenueUsd,
totalRevenueEur: carrier.totalRevenueEur,
preferredCurrency: carrier.preferredCurrency,
lastLoginAt: carrier.lastLoginAt,
};
}
@UseGuards(JwtAuthGuard)
@Patch('change-password')
@ApiBearerAuth()
@ApiOperation({ summary: 'Change carrier password' })
@ApiResponse({ status: 200, description: 'Password changed successfully' })
@ApiResponse({ status: 401, description: 'Invalid old password' })
async changePassword(
@Request() req: any,
@Body() dto: CarrierChangePasswordDto
): Promise<{ message: string }> {
this.logger.log(`Password change request for carrier: ${req.user.carrierId}`);
await this.carrierAuthService.changePassword(
req.user.carrierId,
dto.oldPassword,
dto.newPassword
);
return {
message: 'Password changed successfully',
};
}
@Public()
@Post('request-password-reset')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'Request password reset (sends temporary password)' })
@ApiResponse({ status: 200, description: 'Password reset email sent' })
async requestPasswordReset(
@Body() dto: CarrierPasswordResetRequestDto
): Promise<{ message: string }> {
this.logger.log(`Password reset requested for: ${dto.email}`);
await this.carrierAuthService.requestPasswordReset(dto.email);
return {
message: 'If this email exists, a password reset will be sent',
};
}
@Public()
@Post('verify-auto-login')
@HttpCode(HttpStatus.OK)
@ApiOperation({ summary: 'Verify auto-login token from email link' })
@ApiResponse({ status: 200, description: 'Token verified' })
@ApiResponse({ status: 401, description: 'Invalid or expired token' })
async verifyAutoLoginToken(
@Body() body: { token: string }
): Promise<{ userId: string; carrierId: string }> {
this.logger.log('Verifying auto-login token');
return await this.carrierAuthService.verifyAutoLoginToken(body.token);
}
}