fix(SEC-API-19+20): Validate brain search length and limit params
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
- Add @MaxLength(500) to BrainQueryDto.query and BrainQueryDto.search fields - Create BrainSearchDto with validated q (max 500 chars) and limit (1-100) fields - Update BrainController.search to use BrainSearchDto instead of raw query params - Add defensive validation in BrainService.search and BrainService.query methods: - Reject search terms exceeding 500 characters with BadRequestException - Clamp limit to valid range [1, 100] for defense-in-depth - Add comprehensive tests for DTO validation and service-level guards - Update existing controller tests for new search method signature Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -250,39 +250,33 @@ describe("BrainController", () => {
|
||||
});
|
||||
|
||||
describe("search", () => {
|
||||
it("should call service.search with parameters", async () => {
|
||||
const result = await controller.search("test query", "10", mockWorkspaceId);
|
||||
it("should call service.search with parameters from DTO", async () => {
|
||||
const result = await controller.search({ q: "test query", limit: 10 }, mockWorkspaceId);
|
||||
|
||||
expect(mockService.search).toHaveBeenCalledWith(mockWorkspaceId, "test query", 10);
|
||||
expect(result).toEqual(mockQueryResult);
|
||||
});
|
||||
|
||||
it("should use default limit when not provided", async () => {
|
||||
await controller.search("test", undefined as unknown as string, mockWorkspaceId);
|
||||
it("should use default limit when not provided in DTO", async () => {
|
||||
await controller.search({ q: "test" }, mockWorkspaceId);
|
||||
|
||||
expect(mockService.search).toHaveBeenCalledWith(mockWorkspaceId, "test", 20);
|
||||
});
|
||||
|
||||
it("should cap limit at 100", async () => {
|
||||
await controller.search("test", "500", mockWorkspaceId);
|
||||
it("should handle empty search DTO", async () => {
|
||||
await controller.search({}, mockWorkspaceId);
|
||||
|
||||
expect(mockService.search).toHaveBeenCalledWith(mockWorkspaceId, "test", 100);
|
||||
expect(mockService.search).toHaveBeenCalledWith(mockWorkspaceId, "", 20);
|
||||
});
|
||||
|
||||
it("should handle empty search term", async () => {
|
||||
await controller.search(undefined as unknown as string, "10", mockWorkspaceId);
|
||||
it("should handle undefined q in DTO", async () => {
|
||||
await controller.search({ limit: 10 }, mockWorkspaceId);
|
||||
|
||||
expect(mockService.search).toHaveBeenCalledWith(mockWorkspaceId, "", 10);
|
||||
});
|
||||
|
||||
it("should handle invalid limit", async () => {
|
||||
await controller.search("test", "invalid", mockWorkspaceId);
|
||||
|
||||
expect(mockService.search).toHaveBeenCalledWith(mockWorkspaceId, "test", 20);
|
||||
});
|
||||
|
||||
it("should return search result structure", async () => {
|
||||
const result = await controller.search("test", "10", mockWorkspaceId);
|
||||
const result = await controller.search({ q: "test", limit: 10 }, mockWorkspaceId);
|
||||
|
||||
expect(result).toHaveProperty("tasks");
|
||||
expect(result).toHaveProperty("events");
|
||||
|
||||
Reference in New Issue
Block a user