mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-27 15:30:56 +00:00
232 lines
6.3 KiB
TypeScript
232 lines
6.3 KiB
TypeScript
import {
|
|
Body,
|
|
Controller,
|
|
Post,
|
|
HttpCode,
|
|
HttpStatus,
|
|
UseGuards,
|
|
Get,
|
|
Patch,
|
|
Delete,
|
|
Param,
|
|
Request,
|
|
Query,
|
|
UnauthorizedException,
|
|
} from "@nestjs/common";
|
|
import {
|
|
ApiTags,
|
|
ApiOperation,
|
|
ApiResponse,
|
|
ApiBody,
|
|
ApiBearerAuth,
|
|
} from "@nestjs/swagger";
|
|
import { IsPublic } from "@tria-plc/api-common/modules/auth/decorators/public.decorator";
|
|
import { PassengerAuthService } from "./passenger-auth.service";
|
|
import {
|
|
RegisterDto,
|
|
LoginDto,
|
|
ResendRegistrationCodeDto,
|
|
FaydaRequestPasswordSetupDto,
|
|
FaydaVerifyAndLoginDto,
|
|
} from "./auth.dto";
|
|
import { JwtGuard } from "../../common/jwt.guard";
|
|
|
|
@ApiTags("Passenger Auth")
|
|
@Controller("auth")
|
|
// @Throttle({ auth: { limit: 5, ttl: 60_000 } })
|
|
export class AuthController {
|
|
constructor(private passengerAuthService: PassengerAuthService) {}
|
|
|
|
@Post("register")
|
|
@IsPublic()
|
|
@ApiOperation({
|
|
summary: "Register new passenger account (sends SMS verification code)",
|
|
})
|
|
@ApiResponse({
|
|
status: 201,
|
|
description:
|
|
"Account created as pending. A verification code is sent via SMS — complete signup via PATCH /v1/auth/set-password.",
|
|
})
|
|
@ApiResponse({
|
|
status: 409,
|
|
description: "Email or phone already registered",
|
|
})
|
|
@ApiBody({ type: RegisterDto })
|
|
register(@Request() req: any, @Body() dto: RegisterDto) {
|
|
return this.passengerAuthService.register(dto, req);
|
|
}
|
|
|
|
@Post("register/resend-code")
|
|
@IsPublic()
|
|
@HttpCode(HttpStatus.OK)
|
|
@ApiOperation({
|
|
summary: "Resend the registration verification code for a pending account",
|
|
})
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: "Verification code re-sent if the account is pending.",
|
|
})
|
|
@ApiBody({ type: ResendRegistrationCodeDto })
|
|
resendRegistrationCode(
|
|
@Request() req: any,
|
|
@Body() dto: ResendRegistrationCodeDto,
|
|
) {
|
|
return this.passengerAuthService.resendRegistrationCode(dto, req);
|
|
}
|
|
|
|
@Post("login")
|
|
@IsPublic()
|
|
@HttpCode(HttpStatus.OK)
|
|
@ApiOperation({ summary: "Login with email and password" })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: "Login successful. Returns token + passengerId.",
|
|
})
|
|
@ApiResponse({ status: 401, description: "Invalid credentials" })
|
|
@ApiBody({ type: LoginDto })
|
|
login(@Request() req: any, @Body() dto: LoginDto) {
|
|
return this.passengerAuthService.login(dto, req);
|
|
}
|
|
|
|
@Post("logout")
|
|
@HttpCode(HttpStatus.OK)
|
|
@UseGuards(JwtGuard)
|
|
@ApiBearerAuth("JWT-auth")
|
|
@ApiOperation({ summary: "Logout current user" })
|
|
@ApiResponse({ status: 200, description: "Logout successful" })
|
|
@ApiResponse({ status: 401, description: "Unauthorized" })
|
|
logout(@Request() req: any) {
|
|
if (!req.user?.id)
|
|
throw new UnauthorizedException("User not authenticated");
|
|
return this.passengerAuthService.logout(req.user, req);
|
|
}
|
|
|
|
@Get("me")
|
|
@UseGuards(JwtGuard)
|
|
@ApiBearerAuth("JWT-auth")
|
|
@ApiOperation({
|
|
summary:
|
|
"[DEV] Inspect raw JWT payload — shows full req.user from JwtGuard",
|
|
})
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: "Returns the full req.user object set by JwtGuard",
|
|
})
|
|
@ApiResponse({ status: 401, description: "Unauthorized" })
|
|
getMe(@Request() req: any) {
|
|
return { user: req.user };
|
|
}
|
|
|
|
@Get("profile")
|
|
@UseGuards(JwtGuard)
|
|
@ApiBearerAuth("JWT-auth")
|
|
@ApiOperation({ summary: "Get current user profile" })
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: "User profile retrieved successfully",
|
|
})
|
|
@ApiResponse({ status: 401, description: "Unauthorized" })
|
|
getProfile(@Request() req: any) {
|
|
const userId = req.user?.id;
|
|
if (!userId) throw new UnauthorizedException("User not authenticated");
|
|
return this.passengerAuthService.getProfile(userId);
|
|
}
|
|
|
|
// TODO: admin user management endpoints — implement when admin module is ready
|
|
|
|
@Get("users")
|
|
@UseGuards(JwtGuard)
|
|
@ApiBearerAuth("JWT-auth")
|
|
@ApiOperation({ summary: "List all users (admin)" })
|
|
listUsers(
|
|
@Query("search") search?: string,
|
|
@Query("role") role?: string,
|
|
@Query("status") status?: string,
|
|
@Query("page") page?: string,
|
|
@Query("pageSize") pageSize?: string,
|
|
) {
|
|
return this.passengerAuthService.listUsers({
|
|
search,
|
|
role,
|
|
status,
|
|
page: page ? +page : 1,
|
|
pageSize: pageSize ? +pageSize : 20,
|
|
});
|
|
}
|
|
|
|
@Post("users")
|
|
@UseGuards(JwtGuard)
|
|
@ApiBearerAuth("JWT-auth")
|
|
@ApiOperation({ summary: "Create user (admin)" })
|
|
createUser(@Body() body: any) {
|
|
return this.passengerAuthService.createUser(body);
|
|
}
|
|
|
|
@Patch("users/:id")
|
|
@UseGuards(JwtGuard)
|
|
@ApiBearerAuth("JWT-auth")
|
|
@ApiOperation({ summary: "Update user (admin)" })
|
|
updateUser(@Param("id") id: string, @Body() body: any) {
|
|
return this.passengerAuthService.updateUser(id, body);
|
|
}
|
|
|
|
@Delete("users/:id")
|
|
@UseGuards(JwtGuard)
|
|
@ApiBearerAuth("JWT-auth")
|
|
@ApiOperation({ summary: "Delete user (admin)" })
|
|
deleteUser(@Param("id") id: string) {
|
|
return this.passengerAuthService.deleteUser(id);
|
|
}
|
|
|
|
@Post("users/:id/reset-password")
|
|
@UseGuards(JwtGuard)
|
|
@ApiBearerAuth("JWT-auth")
|
|
@ApiOperation({ summary: "Reset user password (admin)" })
|
|
resetPassword(
|
|
@Param("id") id: string,
|
|
@Body() body: { tempPassword: string },
|
|
) {
|
|
return this.passengerAuthService.resetUserPassword(id, body.tempPassword);
|
|
}
|
|
|
|
@Post("fayda/request-password-setup")
|
|
@IsPublic()
|
|
@HttpCode(HttpStatus.OK)
|
|
@ApiOperation({
|
|
summary: "Send OTP to phone for Fayda-verified account password setup",
|
|
})
|
|
@ApiResponse({
|
|
status: 200,
|
|
description: "OTP sent to registered phone number",
|
|
})
|
|
@ApiBody({ type: FaydaRequestPasswordSetupDto })
|
|
requestFaydaPasswordSetup(
|
|
@Body() dto: FaydaRequestPasswordSetupDto,
|
|
@Request() req: any,
|
|
) {
|
|
return this.passengerAuthService.requestFaydaPasswordSetup(
|
|
dto.phoneNumber,
|
|
req,
|
|
);
|
|
}
|
|
|
|
@Post("fayda/verify-and-login")
|
|
@IsPublic()
|
|
@HttpCode(HttpStatus.OK)
|
|
@ApiOperation({
|
|
summary: "Verify OTP and receive session token for Fayda-verified account",
|
|
})
|
|
@ApiResponse({
|
|
status: 200,
|
|
description:
|
|
"Returns token + requiresPassword flag. Use token with POST /v1/auth/set-fayda-password.",
|
|
})
|
|
@ApiBody({ type: FaydaVerifyAndLoginDto })
|
|
verifyFaydaAndLogin(@Body() dto: FaydaVerifyAndLoginDto) {
|
|
return this.passengerAuthService.verifyFaydaAndLogin(
|
|
dto.phoneNumber,
|
|
dto.otp,
|
|
);
|
|
}
|
|
}
|