import { CanActivate, ExecutionContext, ForbiddenException, Injectable, NotFoundException } from '@nestjs/common'; import { eq } from 'drizzle-orm'; import { DrizzleService } from '../../database/drizzle.service'; import { profile } from '../../database/schema'; /** * Verifies that the profileId in request body/params belongs to the authenticated user. * Expects profileId in: params.profileId OR body.profileId OR query.profileId */ @Injectable() export class ProfileOwnerGuard implements CanActivate { constructor(private readonly drizzleService: DrizzleService) {} async canActivate(context: ExecutionContext): Promise { const request = context.switchToHttp().getRequest(); const userId = request.user?.id; const profileId = request.params?.profileId || request.body?.profileId || request.query?.profileId; if (!profileId) return true; const [found] = await this.drizzleService.db .select({ id: profile.id, userId: profile.userId }) .from(profile) .where(eq(profile.id, profileId)) .limit(1); if (!found) throw new NotFoundException('Profile not found'); if (found.userId !== userId) throw new ForbiddenException('Profile does not belong to you'); request.profile = found; return true; } }