11import {
2+ BadRequestException ,
23 Body ,
34 Controller ,
5+ Delete ,
6+ ForbiddenException ,
47 Get ,
58 HttpStatus ,
69 Logger ,
710 Param ,
11+ ParseUUIDPipe ,
812 Post ,
913 Query ,
1014 Req ,
@@ -15,10 +19,19 @@ import {
1519} from '@nestjs/common' ;
1620import { AuthzService } from './authz.service' ;
1721import { CommonService } from '../../../../libs/common/src/common.service' ;
18- import { ApiBearerAuth , ApiBody , ApiOperation , ApiQuery , ApiResponse , ApiTags } from '@nestjs/swagger' ;
22+ import {
23+ ApiBearerAuth ,
24+ ApiBody ,
25+ ApiForbiddenResponse ,
26+ ApiOperation ,
27+ ApiQuery ,
28+ ApiResponse ,
29+ ApiTags ,
30+ ApiUnauthorizedResponse
31+ } from '@nestjs/swagger' ;
1932import { ApiResponseDto } from '../dtos/apiResponse.dto' ;
2033import { UserEmailVerificationDto } from '../user/dto/create-user.dto' ;
21- import IResponseType from '@credebl/common/interfaces/response.interface' ;
34+ import IResponseType , { IResponse } from '@credebl/common/interfaces/response.interface' ;
2235import { ResponseMessages } from '@credebl/common/response-messages' ;
2336import { Response , Request } from 'express' ;
2437import { EmailVerificationDto } from '../user/dto/email-verify.dto' ;
@@ -36,6 +49,12 @@ import { SessionGuard } from './guards/session.guard';
3649import { UserLogoutDto } from './dtos/user-logout.dto' ;
3750import { AuthGuard } from '@nestjs/passport' ;
3851import { ISessionData } from 'apps/user/interfaces/user.interface' ;
52+ import { ForbiddenErrorDto } from '../dtos/forbidden-error.dto' ;
53+ import { UnauthorizedErrorDto } from '../dtos/unauthorized-error.dto' ;
54+ import { User } from './decorators/user.decorator' ;
55+ import { user } from '@prisma/client' ;
56+ import * as useragent from 'express-useragent' ;
57+
3958@Controller ( 'auth' )
4059@ApiTags ( 'auth' )
4160@UseFilters ( CustomExceptionFilter )
@@ -158,9 +177,19 @@ export class AuthzController {
158177 } )
159178 @ApiResponse ( { status : HttpStatus . OK , description : 'Success' , type : AuthTokenResponse } )
160179 @ApiBody ( { type : LoginUserDto } )
161- async login ( @Body ( ) loginUserDto : LoginUserDto , @Res ( ) res : Response ) : Promise < Response > {
180+ async login ( @Req ( ) req : Request , @ Body ( ) loginUserDto : LoginUserDto , @Res ( ) res : Response ) : Promise < Response > {
162181 if ( loginUserDto . email ) {
163- const userData = await this . authzService . login ( loginUserDto . email , loginUserDto . password ) ;
182+ const ip = ( req . headers [ 'x-forwarded-for' ] as string ) ?. split ( ',' ) [ 0 ] || req . socket . remoteAddress ;
183+ const ua = req . headers [ 'user-agent' ] ;
184+ const expressUa = useragent . parse ( ua ) ;
185+ const device = {
186+ browser : `${ expressUa . browser } ${ expressUa . version ?? '' } ` . trim ( ) ,
187+ os : expressUa . platform ,
188+ deviceType : expressUa . isDesktop ? 'desktop' : 'mobile'
189+ } ;
190+
191+ const clientInfo = JSON . stringify ( { ...device , rawDetail : ua , ip } ) ;
192+ const userData = await this . authzService . login ( clientInfo , loginUserDto . email , loginUserDto . password ) ;
164193
165194 const finalResponse : IResponseType = {
166195 statusCode : HttpStatus . OK ,
@@ -331,4 +360,82 @@ export class AuthzController {
331360
332361 return res . status ( HttpStatus . OK ) . json ( finalResponse ) ;
333362 }
363+
364+ /**
365+ * Get all sessions by userId
366+ * @param userId The ID of the user
367+ * @returns All sessions related to the user
368+ */
369+ @Get ( '/:userId/sessions' )
370+ @ApiOperation ( {
371+ summary : 'Get all sessions by userId' ,
372+ description : 'Retrieve sessions for the user. Based on userId.'
373+ } )
374+ @ApiResponse ( { status : HttpStatus . OK , description : 'Success' , type : ApiResponseDto } )
375+ @ApiUnauthorizedResponse ( { status : HttpStatus . UNAUTHORIZED , description : 'Unauthorized' , type : UnauthorizedErrorDto } )
376+ @ApiForbiddenResponse ( { status : HttpStatus . FORBIDDEN , description : 'Forbidden' , type : ForbiddenErrorDto } )
377+ @ApiBearerAuth ( )
378+ @UseGuards ( AuthGuard ( 'jwt' ) )
379+ async userSessions (
380+ @User ( ) reqUser : user ,
381+ @Res ( ) res : Response ,
382+ @Param (
383+ 'userId' ,
384+ new ParseUUIDPipe ( {
385+ exceptionFactory : ( ) : Error => {
386+ throw new BadRequestException ( `Invalid format for User Id` ) ;
387+ }
388+ } )
389+ )
390+ userId : string
391+ ) : Promise < Response > {
392+ if ( reqUser . id !== userId ) {
393+ throw new ForbiddenException ( 'You are not allowed to access sessions of another user' ) ;
394+ }
395+ const response = await this . authzService . userSessions ( userId ) ;
396+
397+ const finalResponse : IResponse = {
398+ statusCode : HttpStatus . OK ,
399+ message : ResponseMessages . user . success . fetchAllSession ,
400+ data : response
401+ } ;
402+ return res . status ( HttpStatus . OK ) . json ( finalResponse ) ;
403+ }
404+
405+ /**
406+ * Delete session by sessionId
407+ * @param sessionId The ID of the session record to delete
408+ * @returns Acknowledgement on deletion
409+ */
410+ @Delete ( '/:sessionId/sessions' )
411+ @ApiOperation ( {
412+ summary : 'Delete a particular session using its sessionId' ,
413+ description : 'Delete a particular session using its sessionId'
414+ } )
415+ @ApiResponse ( { status : HttpStatus . OK , description : 'Success' , type : ApiResponseDto } )
416+ @ApiUnauthorizedResponse ( { status : HttpStatus . UNAUTHORIZED , description : 'Unauthorized' , type : UnauthorizedErrorDto } )
417+ @ApiForbiddenResponse ( { status : HttpStatus . FORBIDDEN , description : 'Forbidden' , type : ForbiddenErrorDto } )
418+ @ApiBearerAuth ( )
419+ @UseGuards ( AuthGuard ( 'jwt' ) )
420+ async deleteSession (
421+ @User ( ) reqUser : user ,
422+ @Res ( ) res : Response ,
423+ @Param (
424+ 'sessionId' ,
425+ new ParseUUIDPipe ( {
426+ exceptionFactory : ( ) : Error => {
427+ throw new BadRequestException ( `Invalid format for session Id` ) ;
428+ }
429+ } )
430+ )
431+ sessionId : string
432+ ) : Promise < Response > {
433+ const response = await this . authzService . deleteSession ( sessionId , reqUser . id ) ;
434+
435+ const finalResponse : IResponse = {
436+ statusCode : HttpStatus . OK ,
437+ message : response . message
438+ } ;
439+ return res . status ( HttpStatus . OK ) . json ( finalResponse ) ;
440+ }
334441}
0 commit comments