From bdc8c5abcc874fc153202ed4b0607a2f82c5dce8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20S=C3=A1nchez?= Date: Sun, 6 Sep 2026 18:24:33 -0600 Subject: [PATCH 1/2] chore[](): fixed go deps errors --- plugins/crowdstrike/go.mod | 4 ++-- plugins/crowdstrike/go.sum | 4 ++-- plugins/events/go.mod | 4 ++-- plugins/events/go.sum | 6 ++---- plugins/o365/go.mod | 4 ++-- plugins/o365/go.sum | 4 ++-- plugins/sophos/go.mod | 4 ++-- plugins/sophos/go.sum | 4 ++-- 8 files changed, 16 insertions(+), 18 deletions(-) diff --git a/plugins/crowdstrike/go.mod b/plugins/crowdstrike/go.mod index 6c1ea2e33..b22dcd303 100644 --- a/plugins/crowdstrike/go.mod +++ b/plugins/crowdstrike/go.mod @@ -1,6 +1,6 @@ module github.com/utmstack/UTMStack/plugins/crowdstrike -go 1.25.5 +go 1.26.0 require ( github.com/crowdstrike/gofalcon v0.22.0 @@ -87,7 +87,7 @@ require ( go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/arch v0.27.0 // indirect - golang.org/x/crypto v0.55.0 // indirect + golang.org/x/crypto v0.56.0 // indirect golang.org/x/exp v0.0.0-20260603202125-055de637280b // indirect golang.org/x/net v0.57.0 // indirect golang.org/x/oauth2 v0.36.0 // indirect diff --git a/plugins/crowdstrike/go.sum b/plugins/crowdstrike/go.sum index 77acd67b3..b3fa51644 100644 --- a/plugins/crowdstrike/go.sum +++ b/plugins/crowdstrike/go.sum @@ -201,8 +201,8 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.27.0 h1:0WNVcR8u9yFz8j5FvdHpgwNp3FS5U4guYdzHwEiGjoU= golang.org/x/arch v0.27.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8= -golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= -golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= +golang.org/x/crypto v0.56.0 h1:GUh5Ii4J5jtcseSMiRqr1jXCNHoxjeV9Fmekc2oLy6Y= +golang.org/x/crypto v0.56.0/go.mod h1:OMW5y6CY9l38uPLmxU6l6pwcXp1obtLo3e6gT7gQR2I= golang.org/x/exp v0.0.0-20260603202125-055de637280b h1:v1uXiEBHo8QA0LiGCo7UgHMzHT4Kdfpl2zmtH5vaP1Q= golang.org/x/exp v0.0.0-20260603202125-055de637280b/go.mod h1:d2fgXJLVs4dYDHUk5lwMIfzRzSrWCfGZb0ZqeLa/Vcw= golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= diff --git a/plugins/events/go.mod b/plugins/events/go.mod index dea9fdd4b..4ed16cdcb 100644 --- a/plugins/events/go.mod +++ b/plugins/events/go.mod @@ -1,9 +1,9 @@ module github.com/utmstack/UTMStack/plugins/events -go 1.25.5 +go 1.26.0 require ( - github.com/threatwinds/go-sdk v1.1.31 + github.com/threatwinds/go-sdk v1.1.27-0.20260819160318-c56c250bc585 github.com/tidwall/gjson v1.19.0 ) diff --git a/plugins/events/go.sum b/plugins/events/go.sum index bdac5d321..789b6f551 100644 --- a/plugins/events/go.sum +++ b/plugins/events/go.sum @@ -108,10 +108,8 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U= github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U= -github.com/threatwinds/go-sdk v1.1.27-0.20260811073440-251cb9d842cd h1:u5x6DfEkBErQurxPjtFYnd2xfW1ruD6kPxnYzGaHQCc= -github.com/threatwinds/go-sdk v1.1.27-0.20260811073440-251cb9d842cd/go.mod h1:Mr5r+NTTe8k28gVS7EgEorn76VPtf0vPSaUCD2bWRSU= -github.com/threatwinds/go-sdk v1.1.31 h1:H8QNjm+q2zwvOxp+htM5XX/4QDyiZn4Np62MhhUQu7A= -github.com/threatwinds/go-sdk v1.1.31/go.mod h1:aN6Oe3zJop9ngS83oZcKFXDLKWzrny2XhkYm7uoyDbQ= +github.com/threatwinds/go-sdk v1.1.27-0.20260819160318-c56c250bc585 h1:u4YFavEVTKPmYQz5uly0iA8bfzZuwtWmwNjDxU82J7Q= +github.com/threatwinds/go-sdk v1.1.27-0.20260819160318-c56c250bc585/go.mod h1:Mr5r+NTTe8k28gVS7EgEorn76VPtf0vPSaUCD2bWRSU= github.com/tidwall/gjson v1.19.0 h1:xwxm7n691Uf3u5OFjzngavjGTh55KX5q/9w9xHW88JU= github.com/tidwall/gjson v1.19.0/go.mod h1:V37/opeE/JbLUOfH0QTXiNez2l0RUjYUhpT4szFQAfc= github.com/tidwall/match v1.2.0 h1:0pt8FlkOwjN2fPt4bIl4BoNxb98gGHN2ObFEDkrfZnM= diff --git a/plugins/o365/go.mod b/plugins/o365/go.mod index f3d01f1db..15d1f1895 100644 --- a/plugins/o365/go.mod +++ b/plugins/o365/go.mod @@ -1,6 +1,6 @@ module github.com/utmstack/UTMStack/plugins/o365 -go 1.25.5 +go 1.26.0 require ( github.com/fsnotify/fsnotify v1.10.1 @@ -52,7 +52,7 @@ require ( go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/arch v0.27.0 // indirect - golang.org/x/crypto v0.55.0 // indirect + golang.org/x/crypto v0.56.0 // indirect golang.org/x/exp v0.0.0-20260603202125-055de637280b // indirect golang.org/x/net v0.57.0 // indirect golang.org/x/sys v0.47.0 // indirect diff --git a/plugins/o365/go.sum b/plugins/o365/go.sum index 15a8ba3e8..8db200469 100644 --- a/plugins/o365/go.sum +++ b/plugins/o365/go.sum @@ -138,8 +138,8 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.27.0 h1:0WNVcR8u9yFz8j5FvdHpgwNp3FS5U4guYdzHwEiGjoU= golang.org/x/arch v0.27.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8= -golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= -golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= +golang.org/x/crypto v0.56.0 h1:GUh5Ii4J5jtcseSMiRqr1jXCNHoxjeV9Fmekc2oLy6Y= +golang.org/x/crypto v0.56.0/go.mod h1:OMW5y6CY9l38uPLmxU6l6pwcXp1obtLo3e6gT7gQR2I= golang.org/x/exp v0.0.0-20260603202125-055de637280b h1:v1uXiEBHo8QA0LiGCo7UgHMzHT4Kdfpl2zmtH5vaP1Q= golang.org/x/exp v0.0.0-20260603202125-055de637280b/go.mod h1:d2fgXJLVs4dYDHUk5lwMIfzRzSrWCfGZb0ZqeLa/Vcw= golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= diff --git a/plugins/sophos/go.mod b/plugins/sophos/go.mod index a17c0ffe9..ffc52b805 100644 --- a/plugins/sophos/go.mod +++ b/plugins/sophos/go.mod @@ -1,6 +1,6 @@ module github.com/utmstack/UTMStack/plugins/sophos -go 1.25.5 +go 1.26.0 require ( github.com/fsnotify/fsnotify v1.10.1 @@ -52,7 +52,7 @@ require ( go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect golang.org/x/arch v0.27.0 // indirect - golang.org/x/crypto v0.55.0 // indirect + golang.org/x/crypto v0.56.0 // indirect golang.org/x/exp v0.0.0-20260603202125-055de637280b // indirect golang.org/x/net v0.57.0 // indirect golang.org/x/sys v0.47.0 // indirect diff --git a/plugins/sophos/go.sum b/plugins/sophos/go.sum index 15a8ba3e8..8db200469 100644 --- a/plugins/sophos/go.sum +++ b/plugins/sophos/go.sum @@ -138,8 +138,8 @@ go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg= golang.org/x/arch v0.27.0 h1:0WNVcR8u9yFz8j5FvdHpgwNp3FS5U4guYdzHwEiGjoU= golang.org/x/arch v0.27.0/go.mod h1:0X+GdSIP+kL5wPmpK7sdkEVTt2XoYP0cSjQSbZBwOi8= -golang.org/x/crypto v0.55.0 h1:+KWHjbgOaAQ66dh/YlkZKHlz9ZUlq61AFirAR9ntP8M= -golang.org/x/crypto v0.55.0/go.mod h1:uq0V9dE/fzQuJtbnL+2EhWOE63vo164FY8xqEnV9xis= +golang.org/x/crypto v0.56.0 h1:GUh5Ii4J5jtcseSMiRqr1jXCNHoxjeV9Fmekc2oLy6Y= +golang.org/x/crypto v0.56.0/go.mod h1:OMW5y6CY9l38uPLmxU6l6pwcXp1obtLo3e6gT7gQR2I= golang.org/x/exp v0.0.0-20260603202125-055de637280b h1:v1uXiEBHo8QA0LiGCo7UgHMzHT4Kdfpl2zmtH5vaP1Q= golang.org/x/exp v0.0.0-20260603202125-055de637280b/go.mod h1:d2fgXJLVs4dYDHUk5lwMIfzRzSrWCfGZb0ZqeLa/Vcw= golang.org/x/net v0.57.0 h1:K5+3DljvIuDG9/Jv9rvyMywYNFCQ9RSUY6OOTTkT+tE= From 192b43fa59eb2e6f4ca4b52c2c85029033847f99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alex=20S=C3=A1nchez?= Date: Mon, 7 Sep 2026 09:27:55 -0600 Subject: [PATCH 2/2] feat[frontend](soar): http node enrichment-only, add headers and body/headers tabs --- .../soar/components/HttpParamsEditor.tsx | 215 ++++++++++++++++-- .../features/soar/components/NodePalette.tsx | 3 +- .../src/features/soar/types/soar.types.ts | 2 +- frontend/src/shared/i18n/locales/de.json | 4 +- frontend/src/shared/i18n/locales/en.json | 4 +- frontend/src/shared/i18n/locales/es.json | 4 +- frontend/src/shared/i18n/locales/fr.json | 4 +- frontend/src/shared/i18n/locales/it.json | 4 +- frontend/src/shared/i18n/locales/pt.json | 4 +- frontend/src/shared/i18n/locales/ru.json | 4 +- 10 files changed, 217 insertions(+), 31 deletions(-) diff --git a/frontend/src/features/soar/components/HttpParamsEditor.tsx b/frontend/src/features/soar/components/HttpParamsEditor.tsx index 8c86c3850..41ef00f6f 100644 --- a/frontend/src/features/soar/components/HttpParamsEditor.tsx +++ b/frontend/src/features/soar/components/HttpParamsEditor.tsx @@ -1,5 +1,6 @@ import { useEffect, useRef, useState } from 'react' import { useTranslation } from 'react-i18next' +import { Trash2 } from 'lucide-react' import { Input } from '@/shared/components/ui/input' import { cn } from '@/shared/lib/utils' import { isValidHttpUrl, setHttpBodyError } from '../lib/http-node-validity' @@ -30,6 +31,8 @@ interface Props { onChange: (params: HttpParams) => void } +type PayloadTab = 'body' | 'headers' + // ponytail: URL split via one regex, body highlighted via Prism (already // vendored). Validity for save-blocking flows through http-node-validity — // no context wiring. @@ -45,6 +48,7 @@ export function HttpParamsEditor({ nodeId, nodes, params, readOnly, onChange }: const bodyRef = useRef(null) const [bodyText, setBodyText] = useState(() => bodyToText(p.body)) const [bodyError, setBodyError] = useState(null) + const [tab, setTab] = useState('body') useEffect(() => { setBodyText(bodyToText(p.body)) @@ -59,6 +63,10 @@ export function HttpParamsEditor({ nodeId, nodes, params, readOnly, onChange }: } }, [showBody, nodeId]) + useEffect(() => { + if (showBody) setTab('body') + }, [showBody]) + useEffect(() => () => setHttpBodyError(nodeId, null), [nodeId]) const commitUrl = (nextScheme: string, nextRest: string) => { @@ -126,6 +134,23 @@ export function HttpParamsEditor({ nodeId, nodes, params, readOnly, onChange }: } } + const switchTab = (next: PayloadTab) => { + if (next === tab) return + if (tab === 'body') commitBody(bodyText) + setTab(next) + } + + const headers = (showLabel: boolean) => ( + onChange({ ...p, headers: next })} + /> + ) + return (
@@ -183,32 +208,180 @@ export function HttpParamsEditor({ nodeId, nodes, params, readOnly, onChange }: ))}
- {showBody && ( + {showBody ? (
- - {!readOnly && ( -
- +
+ switchTab('body')} + label={t('soar.editor.canvas.http.body')} + /> + switchTab('headers')} + label={t('soar.editor.canvas.http.headers')} + /> +
+ {tab === 'body' ? ( +
+ {!readOnly && ( +
+ +
+ )} + commitBody(bodyText)} + textareaRef={bodyRef} + /> + {bodyError && ( +

+ {t('soar.editor.canvas.http.bodyInvalid')}: {bodyError} +

+ )}
- )} - commitBody(bodyText)} - textareaRef={bodyRef} - /> - {bodyError && ( -

- {t('soar.editor.canvas.http.bodyInvalid')}: {bodyError} -

+ ) : ( + headers(false) )}
+ ) : ( + headers(true) + )} +
+ ) +} + +function TabButton({ active, onClick, label }: { active: boolean; onClick: () => void; label: string }) { + return ( + + ) +} + +function HeaderRows({ + headers, + readOnly, + nodes, + currentNodeId, + showLabel = true, + onChange, +}: { + headers?: Record + readOnly?: boolean + nodes: Record + currentNodeId: string + showLabel?: boolean + onChange: (next: Record | undefined) => void +}) { + const { t } = useTranslation() + const entries = Object.entries(headers ?? {}) + const valueRefs = useRef>([]) + + const commit = (next: Array<[string, string]>) => { + const out: Record = {} + for (const [k, v] of next) { + if (k.trim()) out[k.trim()] = v + } + onChange(Object.keys(out).length > 0 ? out : undefined) + } + + const setAt = (i: number, patch: { key?: string; value?: string }) => { + const next = entries.map(([k, v], j) => + j === i ? ([patch.key ?? k, patch.value ?? v] as [string, string]) : ([k, v] as [string, string]), + ) + commit(next) + } + + const insertIntoValue = (i: number, token: string) => { + const el = valueRefs.current[i] + const cur = entries[i]?.[1] ?? '' + const start = el?.selectionStart ?? cur.length + const end = el?.selectionEnd ?? cur.length + setAt(i, { value: cur.slice(0, start) + token + cur.slice(end) }) + requestAnimationFrame(() => { + const el2 = valueRefs.current[i] + if (!el2) return + el2.focus() + const pos = start + token.length + el2.setSelectionRange(pos, pos) + }) + } + + return ( +
+
+ {showLabel && ( + + )} + {!readOnly && ( + + )} +
+ {entries.length === 0 && readOnly && ( +

—

+ )} +
+ {entries.map(([k, v], i) => ( +
+ setAt(i, { key: e.target.value })} + placeholder="Authorization" + className="h-7 w-2/5 font-mono text-[11px]" + /> + { + valueRefs.current[i] = el + }} + value={v} + readOnly={readOnly} + onChange={(e) => setAt(i, { value: e.target.value })} + placeholder="Bearer $(variables.apiToken)" + className="h-7 flex-1 font-mono text-[11px]" + /> + {!readOnly && ( + <> + insertIntoValue(i, token)} + /> + + + )} +
+ ))} +
) } diff --git a/frontend/src/features/soar/components/NodePalette.tsx b/frontend/src/features/soar/components/NodePalette.tsx index dce0b3c04..505ea262a 100644 --- a/frontend/src/features/soar/components/NodePalette.tsx +++ b/frontend/src/features/soar/components/NodePalette.tsx @@ -13,8 +13,7 @@ const ICONS: Record = { } /** Palette of draggable node types. Each row is one (executor, kind) pair — - * since some executors back both kinds (http, select via kind flag), the - * palette spells them out so the drag payload is unambiguous. */ + * the palette spells them out so the drag payload is unambiguous. */ export function NodePalette({ readOnly }: { readOnly?: boolean }) { const rows: Array<{ meta: ExecutorMeta; kind: NodeKind }> = [] for (const meta of EXECUTOR_CATALOG) { diff --git a/frontend/src/features/soar/types/soar.types.ts b/frontend/src/features/soar/types/soar.types.ts index 27a5d34e3..d25394d91 100644 --- a/frontend/src/features/soar/types/soar.types.ts +++ b/frontend/src/features/soar/types/soar.types.ts @@ -150,7 +150,7 @@ export interface ExecutorMeta { export const EXECUTOR_CATALOG: ExecutorMeta[] = [ { type: 'shell', label: 'Shell (endpoint agent)', kinds: ['executor'] }, - { type: 'http', label: 'HTTP call', kinds: ['executor', 'enrichment'], paramsPlaceholder: { method: 'GET', url: '' } }, + { type: 'http', label: 'HTTP call', kinds: ['enrichment'], paramsPlaceholder: { method: 'GET', url: '' } }, { type: 'llm_enrich', label: 'LLM enrichment', kinds: ['enrichment'], paramsPlaceholder: { prompt: '' } }, { type: 'llm_action', label: 'LLM action', kinds: ['executor'], paramsPlaceholder: { prompt: '' } }, { type: 'notify', label: 'Send notification', kinds: ['executor'], paramsPlaceholder: { message: '', type: 'INFO' } }, diff --git a/frontend/src/shared/i18n/locales/de.json b/frontend/src/shared/i18n/locales/de.json index 6a66de5b1..1c2e6f350 100644 --- a/frontend/src/shared/i18n/locales/de.json +++ b/frontend/src/shared/i18n/locales/de.json @@ -4787,7 +4787,9 @@ "urlInvalid": "Keine gültige http(s)-URL.", "method": "Methode", "body": "Body (JSON)", - "bodyInvalid": "Ungültiges JSON" + "bodyInvalid": "Ungültiges JSON", + "headers": "HTTP-Kopfzeilen", + "addHeader": "Kopfzeile hinzufügen" }, "incident": { "name": "Incident-Name", diff --git a/frontend/src/shared/i18n/locales/en.json b/frontend/src/shared/i18n/locales/en.json index 9123ae8e7..63193ca84 100644 --- a/frontend/src/shared/i18n/locales/en.json +++ b/frontend/src/shared/i18n/locales/en.json @@ -5173,7 +5173,9 @@ "urlInvalid": "Not a valid http(s) URL.", "method": "Method", "body": "Body (JSON)", - "bodyInvalid": "Invalid JSON" + "bodyInvalid": "Invalid JSON", + "headers": "HTTP headers", + "addHeader": "Add header" }, "incident": { "name": "Incident name", diff --git a/frontend/src/shared/i18n/locales/es.json b/frontend/src/shared/i18n/locales/es.json index 3e7720400..93263ecdf 100644 --- a/frontend/src/shared/i18n/locales/es.json +++ b/frontend/src/shared/i18n/locales/es.json @@ -4909,7 +4909,9 @@ "urlInvalid": "URL http(s) inválida.", "method": "Método", "body": "Cuerpo (JSON)", - "bodyInvalid": "JSON inválido" + "bodyInvalid": "JSON inválido", + "headers": "Encabezados HTTP", + "addHeader": "Agregar encabezado" }, "incident": { "name": "Nombre del incidente", diff --git a/frontend/src/shared/i18n/locales/fr.json b/frontend/src/shared/i18n/locales/fr.json index 4fb6fcba9..d2c18f7ea 100644 --- a/frontend/src/shared/i18n/locales/fr.json +++ b/frontend/src/shared/i18n/locales/fr.json @@ -4787,7 +4787,9 @@ "urlInvalid": "URL http(s) invalide.", "method": "Méthode", "body": "Corps (JSON)", - "bodyInvalid": "JSON invalide" + "bodyInvalid": "JSON invalide", + "headers": "En-têtes HTTP", + "addHeader": "Ajouter un en-tête" }, "incident": { "name": "Nom de l'incident", diff --git a/frontend/src/shared/i18n/locales/it.json b/frontend/src/shared/i18n/locales/it.json index bc5d4b8b1..c96a94e2f 100644 --- a/frontend/src/shared/i18n/locales/it.json +++ b/frontend/src/shared/i18n/locales/it.json @@ -4787,7 +4787,9 @@ "urlInvalid": "URL http(s) non valido.", "method": "Metodo", "body": "Corpo (JSON)", - "bodyInvalid": "JSON non valido" + "bodyInvalid": "JSON non valido", + "headers": "Intestazioni HTTP", + "addHeader": "Aggiungi intestazione" }, "incident": { "name": "Nome dell'incidente", diff --git a/frontend/src/shared/i18n/locales/pt.json b/frontend/src/shared/i18n/locales/pt.json index 0c00af3e5..cca39501c 100644 --- a/frontend/src/shared/i18n/locales/pt.json +++ b/frontend/src/shared/i18n/locales/pt.json @@ -4909,7 +4909,9 @@ "urlInvalid": "URL http(s) inválida.", "method": "Método", "body": "Corpo (JSON)", - "bodyInvalid": "JSON inválido" + "bodyInvalid": "JSON inválido", + "headers": "Cabeçalhos HTTP", + "addHeader": "Adicionar cabeçalho" }, "incident": { "name": "Nome do incidente", diff --git a/frontend/src/shared/i18n/locales/ru.json b/frontend/src/shared/i18n/locales/ru.json index 0d36bb1c8..ab9f81e96 100644 --- a/frontend/src/shared/i18n/locales/ru.json +++ b/frontend/src/shared/i18n/locales/ru.json @@ -4579,7 +4579,9 @@ "urlInvalid": "Недопустимый http(s) URL.", "method": "Метод", "body": "Тело (JSON)", - "bodyInvalid": "Недопустимый JSON" + "bodyInvalid": "Недопустимый JSON", + "headers": "HTTP-заголовки", + "addHeader": "Добавить заголовок" }, "incident": { "name": "Название инцидента",