fix(#5,#36): Fix critical security issues and add comprehensive tests
SECURITY FIXES: - Replace generic Error with UnauthorizedException in all controllers - Fix workspace isolation bypass in findAll methods (CRITICAL) - Controllers now always use req.user.workspaceId, never allow query override CODE FIXES: - Fix redundant priority logic in tasks.service.ts - Use TaskPriority.MEDIUM as default instead of undefined TEST ADDITIONS: - Add multi-tenant isolation tests for all services (tasks, events, projects) - Add database constraint violation handling tests (P2002, P2003, P2025) - Add missing controller error tests for events and projects controllers - All new tests verify authentication and workspace isolation RESULTS: - All 247 tests passing - Test coverage: 94.35% (exceeds 85% requirement) - Critical security vulnerabilities fixed Fixes #5 Refs #36 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -9,6 +9,7 @@ import {
|
||||
Query,
|
||||
UseGuards,
|
||||
Request,
|
||||
UnauthorizedException,
|
||||
} from "@nestjs/common";
|
||||
import { ProjectsService } from "./projects.service";
|
||||
import { CreateProjectDto, UpdateProjectDto, QueryProjectsDto } from "./dto";
|
||||
@@ -33,7 +34,7 @@ export class ProjectsController {
|
||||
const userId = req.user?.id;
|
||||
|
||||
if (!workspaceId || !userId) {
|
||||
throw new Error("User workspaceId or userId not found");
|
||||
throw new UnauthorizedException("Authentication required");
|
||||
}
|
||||
|
||||
return this.projectsService.create(workspaceId, userId, createProjectDto);
|
||||
@@ -45,7 +46,10 @@ export class ProjectsController {
|
||||
*/
|
||||
@Get()
|
||||
async findAll(@Query() query: QueryProjectsDto, @Request() req: any) {
|
||||
const workspaceId = req.user?.workspaceId || query.workspaceId;
|
||||
const workspaceId = req.user?.workspaceId;
|
||||
if (!workspaceId) {
|
||||
throw new UnauthorizedException("Authentication required");
|
||||
}
|
||||
return this.projectsService.findAll({ ...query, workspaceId });
|
||||
}
|
||||
|
||||
@@ -57,7 +61,7 @@ export class ProjectsController {
|
||||
async findOne(@Param("id") id: string, @Request() req: any) {
|
||||
const workspaceId = req.user?.workspaceId;
|
||||
if (!workspaceId) {
|
||||
throw new Error("User workspaceId not found");
|
||||
throw new UnauthorizedException("Authentication required");
|
||||
}
|
||||
return this.projectsService.findOne(id, workspaceId);
|
||||
}
|
||||
@@ -76,7 +80,7 @@ export class ProjectsController {
|
||||
const userId = req.user?.id;
|
||||
|
||||
if (!workspaceId || !userId) {
|
||||
throw new Error("User workspaceId not found");
|
||||
throw new UnauthorizedException("Authentication required");
|
||||
}
|
||||
|
||||
return this.projectsService.update(id, workspaceId, userId, updateProjectDto);
|
||||
@@ -92,7 +96,7 @@ export class ProjectsController {
|
||||
const userId = req.user?.id;
|
||||
|
||||
if (!workspaceId || !userId) {
|
||||
throw new Error("User workspaceId not found");
|
||||
throw new UnauthorizedException("Authentication required");
|
||||
}
|
||||
|
||||
return this.projectsService.remove(id, workspaceId, userId);
|
||||
|
||||
Reference in New Issue
Block a user