106 lines
2.8 KiB
TypeScript
Executable File
106 lines
2.8 KiB
TypeScript
Executable File
import { Controller, Get, Put, Patch, Body } from "@nestjs/common";
|
|
import {
|
|
ApiTags,
|
|
ApiBearerAuth,
|
|
ApiOperation,
|
|
ApiOkResponse,
|
|
} from "@nestjs/swagger";
|
|
import { BaseController } from "../../common/base";
|
|
import { UsersService } from "./users.service";
|
|
import {
|
|
CreateUserDto,
|
|
UpdateUserDto,
|
|
UpdateProfileDto,
|
|
ChangePasswordDto,
|
|
} from "./dto/user.dto";
|
|
import { CurrentUser, Roles } from "../../common/decorators";
|
|
import {
|
|
ApiResponse,
|
|
createSuccessResponse,
|
|
} from "../../common/types/api-response.type";
|
|
import { User } from "@prisma/client";
|
|
|
|
import { plainToInstance } from "class-transformer";
|
|
import { UserResponseDto } from "./dto/user.dto";
|
|
|
|
interface AuthenticatedUser {
|
|
id: string;
|
|
email: string;
|
|
role: string;
|
|
}
|
|
|
|
@ApiTags("Users")
|
|
@ApiBearerAuth()
|
|
@Controller("users")
|
|
export class UsersController extends BaseController<
|
|
User,
|
|
CreateUserDto,
|
|
UpdateUserDto
|
|
> {
|
|
constructor(private readonly usersService: UsersService) {
|
|
super(usersService, "User");
|
|
}
|
|
|
|
@Get("me")
|
|
@ApiOperation({ summary: "Get current authenticated user profile" })
|
|
@ApiOkResponse({ type: UserResponseDto })
|
|
async getMe(
|
|
@CurrentUser() user: AuthenticatedUser,
|
|
): Promise<ApiResponse<UserResponseDto>> {
|
|
const fullUser = await this.usersService.findOneWithDetails(user.id);
|
|
return createSuccessResponse(
|
|
plainToInstance(UserResponseDto, fullUser),
|
|
"User profile retrieved successfully",
|
|
);
|
|
}
|
|
|
|
@Put("me")
|
|
@ApiOperation({ summary: "Update current user profile" })
|
|
@ApiOkResponse({ type: UserResponseDto })
|
|
async updateMe(
|
|
@CurrentUser() user: AuthenticatedUser,
|
|
@Body() dto: UpdateProfileDto,
|
|
): Promise<ApiResponse<UserResponseDto>> {
|
|
const updatedUser = await this.usersService.updateProfile(user.id, dto);
|
|
return createSuccessResponse(
|
|
plainToInstance(UserResponseDto, updatedUser),
|
|
"User profile updated successfully",
|
|
);
|
|
}
|
|
|
|
@Patch("me/password")
|
|
@ApiOperation({ summary: "Change current user password" })
|
|
@ApiOkResponse({ description: "Password changed successfully" })
|
|
async changePassword(
|
|
@CurrentUser() user: AuthenticatedUser,
|
|
@Body() dto: ChangePasswordDto,
|
|
): Promise<ApiResponse<null>> {
|
|
await this.usersService.changePassword(
|
|
user.id,
|
|
dto.currentPassword,
|
|
dto.newPassword,
|
|
);
|
|
return createSuccessResponse(null, "Password changed successfully");
|
|
}
|
|
|
|
// Override create to require admin role
|
|
@Roles("admin")
|
|
async create(
|
|
...args: Parameters<
|
|
BaseController<User, CreateUserDto, UpdateUserDto>["create"]
|
|
>
|
|
) {
|
|
return super.create(...args);
|
|
}
|
|
|
|
// Override delete to require admin role
|
|
@Roles("admin")
|
|
async delete(
|
|
...args: Parameters<
|
|
BaseController<User, CreateUserDto, UpdateUserDto>["delete"]
|
|
>
|
|
) {
|
|
return super.delete(...args);
|
|
}
|
|
}
|