From 7bc94b41262f07c7bd9550e61f7197771680f6a3 Mon Sep 17 00:00:00 2001 From: morteza-mortezai Date: Tue, 18 Nov 2025 09:33:50 +0330 Subject: [PATCH] Remove User and AdminUser controllers; update import paths in UserModule to reflect new directory structure. --- src/modules/auth/guards/auth.guard.ts | 50 +++++++++++++++++++ .../{ => controllers}/adminUser.controller.ts | 6 ++- .../{ => controllers}/user.controller.ts | 25 +++------- src/modules/users/user.module.ts | 2 +- 4 files changed, 63 insertions(+), 20 deletions(-) create mode 100644 src/modules/auth/guards/auth.guard.ts rename src/modules/users/{ => controllers}/adminUser.controller.ts (89%) rename src/modules/users/{ => controllers}/user.controller.ts (62%) diff --git a/src/modules/auth/guards/auth.guard.ts b/src/modules/auth/guards/auth.guard.ts new file mode 100644 index 0000000..8feb2d0 --- /dev/null +++ b/src/modules/auth/guards/auth.guard.ts @@ -0,0 +1,50 @@ +import { CanActivate, ExecutionContext, Injectable, UnauthorizedException, Inject } from '@nestjs/common'; +import { Request } from 'express'; +import { JwtService } from '@nestjs/jwt'; +import { ConfigService } from '@nestjs/config'; +import { IAdminTokenPayload, ITokenPayload } from '../interfaces/IToken-payload'; + +export interface AdminAuthRequest extends Request { + adminId: string; + restId: string; +} + +@Injectable() +export class AuthGuard implements CanActivate { + constructor( + @Inject(JwtService) + private readonly jwtService: JwtService, + @Inject(ConfigService) + private readonly configService: ConfigService, + ) {} + + async canActivate(context: ExecutionContext) { + const request = context.switchToHttp().getRequest(); + + try { + const secret = this.configService.get('JWT_SECRET'); + const token = this.extractTokenFromHeader(request); + if (!token) { + throw new UnauthorizedException(); + } + + try { + const payload = await this.jwtService.verifyAsync(token, { + secret, + }); + request['userId'] = payload.userId; + request['restId'] = payload.restId; + } catch { + throw new UnauthorizedException(); + } + return true; + } catch (err) { + console.log('error in AuthGuard', err); + throw new UnauthorizedException('Invalid or expired token'); + } + } + private extractTokenFromHeader(request: Request): string | undefined { + const [type, token] = request.headers.authorization?.split(' ') ?? []; + return type === 'Bearer' ? token : undefined; + } +} diff --git a/src/modules/users/adminUser.controller.ts b/src/modules/users/controllers/adminUser.controller.ts similarity index 89% rename from src/modules/users/adminUser.controller.ts rename to src/modules/users/controllers/adminUser.controller.ts index b022a31..37f16fd 100644 --- a/src/modules/users/adminUser.controller.ts +++ b/src/modules/users/controllers/adminUser.controller.ts @@ -1,11 +1,13 @@ import { Controller, Get, UseGuards, Query, ValidationPipe } from '@nestjs/common'; import { ApiTags, ApiBearerAuth, ApiOperation, ApiOkResponse } from '@nestjs/swagger'; import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; -import { UserService } from './user.service'; -import { FindUsersDto } from './dto/find-user.dto'; +import { UserService } from '../user.service'; +import { FindUsersDto } from '../dto/find-user.dto'; import { UserId } from 'src/common/decorators/user-id.decorator'; import { RestId } from 'src/common/decorators'; +@UseGuards(AdminAuthGuard) +@ApiBearerAuth() @ApiTags('Admin/User') @Controller('admin/user') export class AdminUserController { diff --git a/src/modules/users/user.controller.ts b/src/modules/users/controllers/user.controller.ts similarity index 62% rename from src/modules/users/user.controller.ts rename to src/modules/users/controllers/user.controller.ts index 9d488c3..e309bd5 100644 --- a/src/modules/users/user.controller.ts +++ b/src/modules/users/controllers/user.controller.ts @@ -1,41 +1,32 @@ import { Controller, Get, UseGuards, Patch, Body, ValidationPipe } from '@nestjs/common'; -import { ApiTags, ApiBearerAuth, ApiOperation } from '@nestjs/swagger'; +import { ApiTags, ApiBearerAuth, ApiOperation, ApiBody } from '@nestjs/swagger'; import { AdminAuthGuard } from 'src/modules/auth/guards/adminAuth.guard'; -import { UserService } from './user.service'; -import { UpdateUserDto } from './dto/update-user.dto'; +import { UserService } from '../user.service'; +import { UpdateUserDto } from '../dto/update-user.dto'; import { UserId } from 'src/common/decorators/user-id.decorator'; +@UseGuards(AdminAuthGuard) +@ApiBearerAuth() @ApiTags('User') @Controller('user') export class UserController { constructor(private readonly userService: UserService) {} - @UseGuards(AdminAuthGuard) - @ApiBearerAuth() @ApiOperation({ summary: 'Get the current authenticated user profile' }) @Get('/me') async getUser(@UserId() userId: string) { const user = await this.userService.findById(userId); - return { - message: `GET request: Retrieving profile for authenticated user`, - user, - userId, - }; + return user; } - @UseGuards(AdminAuthGuard) - @ApiBearerAuth() @ApiOperation({ summary: 'Update the authenticated user profile' }) + @ApiBody({ type: UpdateUserDto }) @Patch('/') async updateUser( @UserId() userId: string, @Body(new ValidationPipe({ transform: true, whitelist: true })) dto: UpdateUserDto, ) { const user = await this.userService.updateUser(userId, dto); - return { - message: `PATCH request: Updating profile for user ${userId}`, - userId, - user, - }; + return user; } } diff --git a/src/modules/users/user.module.ts b/src/modules/users/user.module.ts index 79573cf..c2f15f3 100644 --- a/src/modules/users/user.module.ts +++ b/src/modules/users/user.module.ts @@ -1,6 +1,6 @@ import { Module } from '@nestjs/common'; import { UserService } from './user.service'; -import { AdminUserController } from './adminUser.controller'; +import { AdminUserController } from './controllers/adminUser.controller'; import { MikroOrmModule } from '@mikro-orm/nestjs'; import { User } from './entities/user.entity'; import { JwtModule } from '@nestjs/jwt';