diff --git a/html/js/app.js b/html/js/app.js index e58e6aa9..75c28329 100644 --- a/html/js/app.js +++ b/html/js/app.js @@ -197,6 +197,17 @@ $(document).ready(function() { } return content }, + processAncestors(content) { + content = content.toString(); + if (content.replace) { + try { + content = content.replace(/,/g, "\" OR process.entity_id:\""); + } catch (e) { + console.error("Failed to set process ancestors for content: " + e); + } + } + return content + }, replaceActionVar(content, field, value, uriEncode) { if (value === undefined || value == null) return content; @@ -211,6 +222,7 @@ $(document).ready(function() { content = content.replace("{" + field + "|base64}", encode(this.base64encode(value))); content = content.replace("{" + field + "|escape}", encode(this.escape(value))); content = content.replace("{" + field + "|escape|base64}", encode(this.base64encode(this.escape(value)))); + content = content.replace("{" + field + "|processAncestors}", encode(this.processAncestors(value))); return content; }, copyToClipboard(data, style) { diff --git a/html/js/app.test.js b/html/js/app.test.js index 10b8e8de..21a9e384 100644 --- a/html/js/app.test.js +++ b/html/js/app.test.js @@ -20,6 +20,12 @@ test('base64encode', () => { expect(app.base64encode('hello')).toBe('aGVsbG8='); }); +test('processAncestors', () => { + expect(app.processAncestors([])).toBe(''); + expect(app.processAncestors(['asdf1'])).toBe('asdf1'); + expect(app.processAncestors(['asdf1','asdf2','asdf3'])).toBe('asdf1\" OR process.entity_id:\"asdf2\" OR process.entity_id:\"asdf3'); +}); + test('replaceActionVar', () => { expect(app.replaceActionVar('test here', 'foo', 'bar', true)).toBe('test here'); expect(app.replaceActionVar('test {bar} here', 'foo', 'bar', true)).toBe('test {bar} here'); @@ -30,15 +36,13 @@ test('replaceActionVar', () => { expect(app.replaceActionVar('test {foo|escape} here', 'foo', 'sand "bar\\bad"', true)).toBe('test sand%20%5C%22bar%5C%5Cbad%5C%22 here'); expect(app.replaceActionVar('test {foo|escape|base64} here', 'foo', 'sand "bar\\bad"', false)).toBe('test c2FuZCBcImJhclxcYmFkXCI= here'); expect(app.replaceActionVar('test {foo|escape|base64} here', 'foo', 'sand "bar\\bad"', true)).toBe('test c2FuZCBcImJhclxcYmFkXCI%3D here'); + expect(app.replaceActionVar('test {foo|processAncestors} here', 'foo', '', true)).toBe('test here'); + expect(app.replaceActionVar('test {foo|processAncestors} here', 'foo', 'bar', true)).toBe('test bar here'); + expect(app.replaceActionVar('test {foo|processAncestors} here', 'foo', ['asdf1','asdf2','asdf3'], true)).toBe('test asdf1%22%20OR%20process.entity_id%3A%22asdf2%22%20OR%20process.entity_id%3A%22asdf3 here'); expect(app.replaceActionVar('test {foo} here', 'foo', null, true)).toBe('test {foo} here'); expect(app.replaceActionVar('test {foo} here', 'foo', undefined, true)).toBe('test {foo} here'); }); -test('base64encode', () => { - expect(app.base64encode('')).toBe(''); - expect(app.base64encode('hello')).toBe('aGVsbG8='); -}); - test('formatMarkdown', () => { expect(app.formatMarkdown('```code```')).toBe('

code

\n'); expect(app.formatMarkdown('bad')).toBe('

bad

\n'); @@ -461,4 +465,4 @@ test('checkForUnauthorized', () => { testCheckForUnauthorized('/foo/', {}, null, false); testCheckForUnauthorized('/login/banner.md', {}, '/blah', false); testCheckForUnauthorized('/auth/self-service/login/browser', {}, '/blah', true); -}); \ No newline at end of file +}); diff --git a/html/js/i18n.js b/html/js/i18n.js index 843d1c35..385472ed 100644 --- a/html/js/i18n.js +++ b/html/js/i18n.js @@ -34,6 +34,10 @@ const i18n = { actionHuntHelp: 'Hunt for this field', actionPcap: 'PCAP', actionPcapHelp: 'Show PCAP for this event', + actionProcessAncestors: 'Process ancestors', + actionProcessAncestorsHelp: 'Show all parent processes for this process', + actionSublime: 'Sublime Platform Email Review', + actionSublimeHelp: 'Review email in Sublime Platform', actionSuccess: 'Action completed: ', actionVirusTotal: 'VirusTotal', actionVirusTotalHelp: 'Analyze this field at virustotal.com',