153 lines
4.7 KiB
TypeScript
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);
|
|
}
|
|
}
|