From 21673f46de171a6051a63a47d9b96906c82ffcae Mon Sep 17 00:00:00 2001 From: Pooja Date: Tue, 27 Jan 2026 22:06:17 +0530 Subject: [PATCH] feat: add header validation (#6859) * feat: add header validation * fix: test stability * fix: scope the locator --------- Co-authored-by: Sid --- .../CollectionSettings/Headers/index.js | 18 ++++ .../src/components/EditableTable/index.js | 50 +++++----- .../FolderSettings/Headers/index.js | 18 ++++ .../RequestPane/RequestHeaders/index.js | 22 ++++- packages/bruno-app/src/utils/common/regex.js | 6 ++ .../request/headers/header-validation.spec.ts | 93 +++++++++++++++++++ tests/utils/page/actions.ts | 13 ++- 7 files changed, 192 insertions(+), 28 deletions(-) create mode 100644 tests/request/headers/header-validation.spec.ts diff --git a/packages/bruno-app/src/components/CollectionSettings/Headers/index.js b/packages/bruno-app/src/components/CollectionSettings/Headers/index.js index 4a29293ed..9eb0a6dd3 100644 --- a/packages/bruno-app/src/components/CollectionSettings/Headers/index.js +++ b/packages/bruno-app/src/components/CollectionSettings/Headers/index.js @@ -11,6 +11,7 @@ import { headers as StandardHTTPHeaders } from 'know-your-http-well'; import { MimeTypes } from 'utils/codemirror/autocompleteConstants'; import BulkEditor from 'components/BulkEditor/index'; import Button from 'ui/Button'; +import { headerNameRegex, headerValueRegex } from 'utils/common/regex'; const headerAutoCompleteList = StandardHTTPHeaders.map((e) => e.header); @@ -32,6 +33,22 @@ const Headers = ({ collection }) => { const handleSave = () => dispatch(saveCollectionSettings(collection.uid)); + const getRowError = useCallback((row, index, key) => { + if (key === 'name') { + if (!row.name || row.name.trim() === '') return null; + if (!headerNameRegex.test(row.name)) { + return 'Header name cannot contain spaces or newlines'; + } + } + if (key === 'value') { + if (!row.value) return null; + if (!headerValueRegex.test(row.value)) { + return 'Header value cannot contain newlines'; + } + } + return null; + }, []); + const columns = [ { key: 'name', @@ -101,6 +118,7 @@ const Headers = ({ collection }) => { rows={headers} onChange={handleHeadersChange} defaultRow={defaultRow} + getRowError={getRowError} />
); }, [isLastEmptyRow, getRowError, handleValueChange]); diff --git a/packages/bruno-app/src/components/FolderSettings/Headers/index.js b/packages/bruno-app/src/components/FolderSettings/Headers/index.js index d63786e38..1ac148368 100644 --- a/packages/bruno-app/src/components/FolderSettings/Headers/index.js +++ b/packages/bruno-app/src/components/FolderSettings/Headers/index.js @@ -11,6 +11,7 @@ import { headers as StandardHTTPHeaders } from 'know-your-http-well'; import { MimeTypes } from 'utils/codemirror/autocompleteConstants'; import BulkEditor from 'components/BulkEditor/index'; import Button from 'ui/Button'; +import { headerNameRegex, headerValueRegex } from 'utils/common/regex'; const headerAutoCompleteList = StandardHTTPHeaders.map((e) => e.header); @@ -36,6 +37,22 @@ const Headers = ({ collection, folder }) => { const handleSave = () => dispatch(saveFolderRoot(collection.uid, folder.uid)); + const getRowError = useCallback((row, index, key) => { + if (key === 'name') { + if (!row.name || row.name.trim() === '') return null; + if (!headerNameRegex.test(row.name)) { + return 'Header name cannot contain spaces or newlines'; + } + } + if (key === 'value') { + if (!row.value) return null; + if (!headerValueRegex.test(row.value)) { + return 'Header value cannot contain newlines'; + } + } + return null; + }, []); + const columns = [ { key: 'name', @@ -106,6 +123,7 @@ const Headers = ({ collection, folder }) => { rows={headers} onChange={handleHeadersChange} defaultRow={defaultRow} + getRowError={getRowError} />