import { Injectable, CanActivate, ExecutionContext, ForbiddenException } from '@nestjs/common'; import { PrismaService } from './prisma.service.js'; @Injectable() export class TourRoleGuard implements CanActivate { constructor(private prisma: PrismaService) {} async canActivate(context: ExecutionContext): Promise { const request = context.switchToHttp().getRequest(); const user = request.user; const tourId = request.params.id || request.params.tourId; const path = request.url; if (!user || !tourId) { throw new ForbiddenException("Thông tin xác thực hoặc mã Tour không hợp lệ."); } if (path.includes('/join-requests') && request.method === 'POST' && (!request.params.requestId || /\/join-requests\/[^/]+\/(accept|reject)$/.test(path))) { request.tourParticipation = null; return true; } const participation = await this.prisma.tourParticipant.findUnique({ where: { tourId_userId: { tourId: tourId, userId: user.id, }, }, }); if (!participation) { throw new ForbiddenException("Bạn không phải là thành viên của tour này."); } request.tourParticipation = participation; const role = participation.role; const isPlanPath = path.includes('/plans'); const isExpensePath = path.includes('/expenses'); if ( (role === 'MEMBER_NO_FINANCE' || role === 'VIEWER_ONLY') && (isPlanPath || isExpensePath) ) { throw new ForbiddenException("Bạn không có quyền xem kế hoạch và chi phí của tour này."); } return true; } }