This commit is contained in:
@@ -27,12 +27,7 @@ import {
|
||||
ApiResponse,
|
||||
ApiBody,
|
||||
} from '@nestjs/swagger';
|
||||
import { Request } from 'express';
|
||||
|
||||
// สร้าง Interface สำหรับ Request ที่มี User
|
||||
interface RequestWithUser extends Request {
|
||||
user: any;
|
||||
}
|
||||
import type { RequestWithUser, RequestWithRefreshUser } from '../interfaces/request-with-user.interface';
|
||||
|
||||
@ApiTags('Authentication')
|
||||
@Controller('auth')
|
||||
@@ -95,7 +90,7 @@ export class AuthController {
|
||||
},
|
||||
},
|
||||
})
|
||||
async refresh(@Req() req: RequestWithUser) {
|
||||
async refresh(@Req() req: RequestWithRefreshUser) {
|
||||
return this.authService.refreshToken(req.user.sub, req.user.refreshToken);
|
||||
}
|
||||
|
||||
@@ -121,7 +116,7 @@ export class AuthController {
|
||||
}
|
||||
// ส่ง refresh token ไปด้วยถ้ามี (ใน header หรือ body)
|
||||
// สำหรับตอนนี้ส่งแค่ access token ไป blacklist
|
||||
return this.authService.logout(req.user.sub, token);
|
||||
return this.authService.logout(req.user.user_id, token);
|
||||
}
|
||||
|
||||
@UseGuards(JwtAuthGuard)
|
||||
|
||||
@@ -17,6 +17,7 @@ import {
|
||||
import { AuthService } from './auth.service';
|
||||
import { JwtAuthGuard } from '../guards/jwt-auth.guard';
|
||||
import { User } from '../../modules/user/entities/user.entity';
|
||||
import type { RequestWithUser } from '../interfaces/request-with-user.interface';
|
||||
|
||||
@ApiTags('Authentication')
|
||||
@Controller('auth/sessions')
|
||||
@@ -28,7 +29,7 @@ export class SessionController {
|
||||
@Get()
|
||||
@ApiOperation({ summary: 'List all active sessions (Admin/DC Only)' })
|
||||
@ApiResponse({ status: 200, description: 'List of active sessions' })
|
||||
async getActiveSessions(@Req() req: any) {
|
||||
async getActiveSessions(@Req() req: RequestWithUser) {
|
||||
this.checkAdminRole(req.user);
|
||||
return this.authService.getActiveSessions();
|
||||
}
|
||||
@@ -36,7 +37,10 @@ export class SessionController {
|
||||
@Delete(':id')
|
||||
@ApiOperation({ summary: 'Revoke a session by ID (Admin/DC Only)' })
|
||||
@ApiResponse({ status: 200, description: 'Session revoked' })
|
||||
async revokeSession(@Param('id', ParseIntPipe) id: number, @Req() req: any) {
|
||||
async revokeSession(
|
||||
@Param('id', ParseIntPipe) id: number,
|
||||
@Req() req: RequestWithUser
|
||||
) {
|
||||
this.checkAdminRole(req.user);
|
||||
await this.authService.revokeSession(id);
|
||||
return { message: 'Session revoked successfully' };
|
||||
|
||||
@@ -7,11 +7,12 @@ import { PassportStrategy } from '@nestjs/passport';
|
||||
import { Injectable } from '@nestjs/common';
|
||||
import { ConfigService } from '@nestjs/config';
|
||||
import { Request } from 'express';
|
||||
import type { JwtPayload } from './jwt.strategy';
|
||||
|
||||
@Injectable()
|
||||
export class JwtRefreshStrategy extends PassportStrategy(
|
||||
Strategy,
|
||||
'jwt-refresh',
|
||||
'jwt-refresh'
|
||||
) {
|
||||
constructor(configService: ConfigService) {
|
||||
super({
|
||||
@@ -23,7 +24,7 @@ export class JwtRefreshStrategy extends PassportStrategy(
|
||||
});
|
||||
}
|
||||
|
||||
async validate(req: Request, payload: any) {
|
||||
async validate(req: Request, payload: JwtPayload) {
|
||||
const refreshToken = ExtractJwt.fromAuthHeaderAsBearerToken()(req);
|
||||
return {
|
||||
...payload,
|
||||
|
||||
@@ -20,14 +20,7 @@ import type { Response } from 'express';
|
||||
import { FileInterceptor } from '@nestjs/platform-express';
|
||||
import { FileStorageService } from './file-storage.service';
|
||||
import { JwtAuthGuard } from '../guards/jwt-auth.guard';
|
||||
|
||||
// Interface เพื่อระบุ Type ของ Request ที่ผ่าน JwtAuthGuard มาแล้ว
|
||||
interface RequestWithUser {
|
||||
user: {
|
||||
userId: number;
|
||||
username: string;
|
||||
};
|
||||
}
|
||||
import type { RequestWithUser } from '../interfaces/request-with-user.interface';
|
||||
|
||||
@Controller('files')
|
||||
@UseGuards(JwtAuthGuard)
|
||||
@@ -53,7 +46,7 @@ export class FileStorageController {
|
||||
@Request() req: RequestWithUser
|
||||
) {
|
||||
// ส่ง userId จาก Token ไปด้วย
|
||||
return this.fileStorageService.upload(file, req.user.userId);
|
||||
return this.fileStorageService.upload(file, req.user.user_id);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -90,7 +83,7 @@ export class FileStorageController {
|
||||
@Request() req: RequestWithUser
|
||||
) {
|
||||
// ส่ง userId ไปด้วยเพื่อตรวจสอบความเป็นเจ้าของ
|
||||
await this.fileStorageService.delete(id, req.user.userId);
|
||||
await this.fileStorageService.delete(id, req.user.user_id);
|
||||
return { message: 'File deleted successfully', id };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,30 @@
|
||||
// File: src/common/interfaces/request-with-user.interface.ts
|
||||
// NestJS 11: Shared typed Request interfaces (replaces scattered `req: any` patterns)
|
||||
|
||||
import { Request } from 'express';
|
||||
import { User } from '../../modules/user/entities/user.entity';
|
||||
|
||||
/**
|
||||
* Request object after JwtAuthGuard has validated the token.
|
||||
* Passport attaches the User entity returned by JwtStrategy.validate() to `req.user`.
|
||||
*/
|
||||
export interface RequestWithUser extends Request {
|
||||
user: User;
|
||||
}
|
||||
|
||||
/**
|
||||
* Payload shape returned by JwtRefreshStrategy.validate().
|
||||
* Contains JWT claims + the raw refresh token for rotation.
|
||||
*/
|
||||
export interface JwtRefreshPayload {
|
||||
sub: number;
|
||||
username: string;
|
||||
refreshToken: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Request object after JwtRefreshGuard has validated the refresh token.
|
||||
*/
|
||||
export interface RequestWithRefreshUser extends Request {
|
||||
user: JwtRefreshPayload;
|
||||
}
|
||||
Reference in New Issue
Block a user