mirror of
https://github.com/gchq/CyberChef
synced 2026-01-19 08:53:47 +00:00
Compare commits
21 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
de762847e9 | ||
|
|
6248e32148 | ||
|
|
52f88ee32d | ||
|
|
f8d1cf2f60 | ||
|
|
e129425d8d | ||
|
|
ae20d82e1d | ||
|
|
463b2ce040 | ||
|
|
412b47abba | ||
|
|
ed216eee73 | ||
|
|
9dd5234962 | ||
|
|
018532016b | ||
|
|
7dfecc38f6 | ||
|
|
572f035877 | ||
|
|
b94eb6adb0 | ||
|
|
45fccb94e1 | ||
|
|
2628f17fae | ||
|
|
69fb6e77fc | ||
|
|
82b5e97a2b | ||
|
|
7f168d49a6 | ||
|
|
b491b9d77d | ||
|
|
237f792fb4 |
10
CHANGELOG.md
10
CHANGELOG.md
@@ -2,6 +2,12 @@
|
|||||||
All major and minor version changes will be documented in this file. Details of patch-level version changes can be found in [commit messages](https://github.com/gchq/CyberChef/commits/master).
|
All major and minor version changes will be documented in this file. Details of patch-level version changes can be found in [commit messages](https://github.com/gchq/CyberChef/commits/master).
|
||||||
|
|
||||||
|
|
||||||
|
### [9.4.0] - 2019-08-30
|
||||||
|
- 'Render Markdown' operation added [@j433866] | [#627]
|
||||||
|
|
||||||
|
### [9.3.0] - 2019-08-30
|
||||||
|
- 'Show on map' operation added [@j433866] | [#477]
|
||||||
|
|
||||||
### [9.2.0] - 2019-08-23
|
### [9.2.0] - 2019-08-23
|
||||||
- 'Parse UDP' operation added [@h345983745] | [#614]
|
- 'Parse UDP' operation added [@h345983745] | [#614]
|
||||||
|
|
||||||
@@ -170,6 +176,8 @@ All major and minor version changes will be documented in this file. Details of
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
[9.4.0]: https://github.com/gchq/CyberChef/releases/tag/v9.4.0
|
||||||
|
[9.3.0]: https://github.com/gchq/CyberChef/releases/tag/v9.3.0
|
||||||
[9.2.0]: https://github.com/gchq/CyberChef/releases/tag/v9.2.0
|
[9.2.0]: https://github.com/gchq/CyberChef/releases/tag/v9.2.0
|
||||||
[9.1.0]: https://github.com/gchq/CyberChef/releases/tag/v9.1.0
|
[9.1.0]: https://github.com/gchq/CyberChef/releases/tag/v9.1.0
|
||||||
[9.0.0]: https://github.com/gchq/CyberChef/releases/tag/v9.0.0
|
[9.0.0]: https://github.com/gchq/CyberChef/releases/tag/v9.0.0
|
||||||
@@ -279,6 +287,7 @@ All major and minor version changes will be documented in this file. Details of
|
|||||||
[#467]: https://github.com/gchq/CyberChef/pull/467
|
[#467]: https://github.com/gchq/CyberChef/pull/467
|
||||||
[#468]: https://github.com/gchq/CyberChef/pull/468
|
[#468]: https://github.com/gchq/CyberChef/pull/468
|
||||||
[#476]: https://github.com/gchq/CyberChef/pull/476
|
[#476]: https://github.com/gchq/CyberChef/pull/476
|
||||||
|
[#477]: https://github.com/gchq/CyberChef/pull/477
|
||||||
[#489]: https://github.com/gchq/CyberChef/pull/489
|
[#489]: https://github.com/gchq/CyberChef/pull/489
|
||||||
[#496]: https://github.com/gchq/CyberChef/pull/496
|
[#496]: https://github.com/gchq/CyberChef/pull/496
|
||||||
[#506]: https://github.com/gchq/CyberChef/pull/506
|
[#506]: https://github.com/gchq/CyberChef/pull/506
|
||||||
@@ -296,3 +305,4 @@ All major and minor version changes will be documented in this file. Details of
|
|||||||
[#591]: https://github.com/gchq/CyberChef/pull/591
|
[#591]: https://github.com/gchq/CyberChef/pull/591
|
||||||
[#595]: https://github.com/gchq/CyberChef/pull/595
|
[#595]: https://github.com/gchq/CyberChef/pull/595
|
||||||
[#614]: https://github.com/gchq/CyberChef/pull/614
|
[#614]: https://github.com/gchq/CyberChef/pull/614
|
||||||
|
[#627]: https://github.com/gchq/CyberChef/pull/627
|
||||||
|
|||||||
41
package-lock.json
generated
41
package-lock.json
generated
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cyberchef",
|
"name": "cyberchef",
|
||||||
"version": "9.2.3",
|
"version": "9.4.0",
|
||||||
"lockfileVersion": 1,
|
"lockfileVersion": 1,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
@@ -2068,7 +2068,6 @@
|
|||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"sprintf-js": "~1.0.2"
|
"sprintf-js": "~1.0.2"
|
||||||
}
|
}
|
||||||
@@ -4786,6 +4785,11 @@
|
|||||||
"tapable": "^1.0.0"
|
"tapable": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"entities": {
|
||||||
|
"version": "1.1.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
|
||||||
|
"integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w=="
|
||||||
|
},
|
||||||
"errno": {
|
"errno": {
|
||||||
"version": "0.1.7",
|
"version": "0.1.7",
|
||||||
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
|
"resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
|
||||||
@@ -8786,6 +8790,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/libyara-wasm/-/libyara-wasm-0.0.12.tgz",
|
"resolved": "https://registry.npmjs.org/libyara-wasm/-/libyara-wasm-0.0.12.tgz",
|
||||||
"integrity": "sha512-AjTe4FiBuH4F7HwGT/3UxoRenczXtrbM6oWGrifxb44LrkDh5VxRNg9zwfPpDA5Fcc1iYcXS0WVA/b3DGtD8cQ=="
|
"integrity": "sha512-AjTe4FiBuH4F7HwGT/3UxoRenczXtrbM6oWGrifxb44LrkDh5VxRNg9zwfPpDA5Fcc1iYcXS0WVA/b3DGtD8cQ=="
|
||||||
},
|
},
|
||||||
|
"linkify-it": {
|
||||||
|
"version": "2.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz",
|
||||||
|
"integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==",
|
||||||
|
"requires": {
|
||||||
|
"uc.micro": "^1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"livereload-js": {
|
"livereload-js": {
|
||||||
"version": "2.4.0",
|
"version": "2.4.0",
|
||||||
"resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz",
|
"resolved": "https://registry.npmjs.org/livereload-js/-/livereload-js-2.4.0.tgz",
|
||||||
@@ -9141,6 +9153,18 @@
|
|||||||
"object-visit": "^1.0.0"
|
"object-visit": "^1.0.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"markdown-it": {
|
||||||
|
"version": "9.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-9.1.0.tgz",
|
||||||
|
"integrity": "sha512-xHKG4C8iPriyfu/jc2hsCC045fKrMQ0VexX2F1FGYiRxDxqMB2aAhF8WauJ3fltn2kb90moGBkiiEdooGIg55w==",
|
||||||
|
"requires": {
|
||||||
|
"argparse": "^1.0.7",
|
||||||
|
"entities": "~1.1.1",
|
||||||
|
"linkify-it": "^2.0.0",
|
||||||
|
"mdurl": "^1.0.1",
|
||||||
|
"uc.micro": "^1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
"md5.js": {
|
"md5.js": {
|
||||||
"version": "1.3.5",
|
"version": "1.3.5",
|
||||||
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
|
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
|
||||||
@@ -9152,6 +9176,11 @@
|
|||||||
"safe-buffer": "^5.1.2"
|
"safe-buffer": "^5.1.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"mdurl": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4="
|
||||||
|
},
|
||||||
"media-typer": {
|
"media-typer": {
|
||||||
"version": "0.3.0",
|
"version": "0.3.0",
|
||||||
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
|
||||||
@@ -12677,8 +12706,7 @@
|
|||||||
"sprintf-js": {
|
"sprintf-js": {
|
||||||
"version": "1.0.3",
|
"version": "1.0.3",
|
||||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
|
||||||
"dev": true
|
|
||||||
},
|
},
|
||||||
"ssdeep.js": {
|
"ssdeep.js": {
|
||||||
"version": "0.0.2",
|
"version": "0.0.2",
|
||||||
@@ -13596,6 +13624,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz",
|
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.20.tgz",
|
||||||
"integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw=="
|
"integrity": "sha512-8OaIKfzL5cpx8eCMAhhvTlft8GYF8b2eQr6JkCyVdrgjcytyOmPCXrqXFcUnhonRpLlh5yxEZVohm6mzaowUOw=="
|
||||||
},
|
},
|
||||||
|
"uc.micro": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
|
||||||
|
"integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA=="
|
||||||
|
},
|
||||||
"uglify-js": {
|
"uglify-js": {
|
||||||
"version": "3.6.0",
|
"version": "3.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.0.tgz",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "cyberchef",
|
"name": "cyberchef",
|
||||||
"version": "9.2.3",
|
"version": "9.4.0",
|
||||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||||
"author": "n1474335 <n1474335@gmail.com>",
|
"author": "n1474335 <n1474335@gmail.com>",
|
||||||
"homepage": "https://gchq.github.io/CyberChef",
|
"homepage": "https://gchq.github.io/CyberChef",
|
||||||
@@ -126,6 +126,7 @@
|
|||||||
"lodash": "^4.17.15",
|
"lodash": "^4.17.15",
|
||||||
"loglevel": "^1.6.3",
|
"loglevel": "^1.6.3",
|
||||||
"loglevel-message-prefix": "^3.0.0",
|
"loglevel-message-prefix": "^3.0.0",
|
||||||
|
"markdown-it": "^9.0.0",
|
||||||
"moment": "^2.24.0",
|
"moment": "^2.24.0",
|
||||||
"moment-timezone": "^0.5.25",
|
"moment-timezone": "^0.5.25",
|
||||||
"ngeohash": "^0.6.3",
|
"ngeohash": "^0.6.3",
|
||||||
|
|||||||
@@ -1303,6 +1303,30 @@ export function sendStatusMessage(msg) {
|
|||||||
console.debug(msg);
|
console.debug(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const debounceTimeouts = {};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debouncer to stop functions from being executed multiple times in a
|
||||||
|
* short space of time
|
||||||
|
* https://davidwalsh.name/javascript-debounce-function
|
||||||
|
*
|
||||||
|
* @param {function} func - The function to be executed after the debounce time
|
||||||
|
* @param {number} wait - The time (ms) to wait before executing the function
|
||||||
|
* @param {string} id - Unique ID to reference the timeout for the function
|
||||||
|
* @param {object} scope - The object to bind to the debounced function
|
||||||
|
* @param {array} args - Array of arguments to be passed to func
|
||||||
|
* @returns {function}
|
||||||
|
*/
|
||||||
|
export function debounce(func, wait, id, scope, args) {
|
||||||
|
return function() {
|
||||||
|
const later = function() {
|
||||||
|
func.apply(scope, args);
|
||||||
|
};
|
||||||
|
clearTimeout(debounceTimeouts[id]);
|
||||||
|
debounceTimeouts[id] = setTimeout(later, wait);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Polyfills
|
* Polyfills
|
||||||
|
|||||||
@@ -228,6 +228,7 @@
|
|||||||
"Convert speed",
|
"Convert speed",
|
||||||
"Convert data units",
|
"Convert data units",
|
||||||
"Convert co-ordinate format",
|
"Convert co-ordinate format",
|
||||||
|
"Show on map",
|
||||||
"Parse UNIX file permissions",
|
"Parse UNIX file permissions",
|
||||||
"Swap endianness",
|
"Swap endianness",
|
||||||
"Parse colour code",
|
"Parse colour code",
|
||||||
@@ -357,7 +358,8 @@
|
|||||||
"BSON serialise",
|
"BSON serialise",
|
||||||
"BSON deserialise",
|
"BSON deserialise",
|
||||||
"To MessagePack",
|
"To MessagePack",
|
||||||
"From MessagePack"
|
"From MessagePack",
|
||||||
|
"Render Markdown"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
69
src/core/operations/RenderMarkdown.mjs
Normal file
69
src/core/operations/RenderMarkdown.mjs
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
/**
|
||||||
|
* @author j433866 [j433866@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2019
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation.mjs";
|
||||||
|
import MarkdownIt from "markdown-it";
|
||||||
|
import hljs from "highlight.js";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Render Markdown operation
|
||||||
|
*/
|
||||||
|
class RenderMarkdown extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RenderMarkdown constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Render Markdown";
|
||||||
|
this.module = "Code";
|
||||||
|
this.description = "Renders input Markdown as HTML. HTML rendering is disabled to avoid XSS.";
|
||||||
|
this.infoURL = "https://wikipedia.org/wiki/Markdown";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "html";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
name: "Autoconvert URLs to links",
|
||||||
|
type: "boolean",
|
||||||
|
value: false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Enable syntax highlighting",
|
||||||
|
type: "boolean",
|
||||||
|
value: true
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {html}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
const [convertLinks, enableHighlighting] = args,
|
||||||
|
md = new MarkdownIt({
|
||||||
|
linkify: convertLinks,
|
||||||
|
html: false, // Explicitly disable HTML rendering
|
||||||
|
highlight: function(str, lang) {
|
||||||
|
if (lang && hljs.getLanguage(lang) && enableHighlighting) {
|
||||||
|
try {
|
||||||
|
return hljs.highlight(lang, str).value;
|
||||||
|
} catch (__) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
rendered = md.render(input);
|
||||||
|
|
||||||
|
return `<div style="font-family: var(--primary-font-family)">${rendered}</div>`;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export default RenderMarkdown;
|
||||||
113
src/core/operations/ShowOnMap.mjs
Normal file
113
src/core/operations/ShowOnMap.mjs
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
/**
|
||||||
|
* @author j433866 [j433866@gmail.com]
|
||||||
|
* @copyright Crown Copyright 2019
|
||||||
|
* @license Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Operation from "../Operation.mjs";
|
||||||
|
import {FORMATS, convertCoordinates} from "../lib/ConvertCoordinates.mjs";
|
||||||
|
import OperationError from "../errors/OperationError.mjs";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show on map operation
|
||||||
|
*/
|
||||||
|
class ShowOnMap extends Operation {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ShowOnMap constructor
|
||||||
|
*/
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this.name = "Show on map";
|
||||||
|
this.module = "Hashing";
|
||||||
|
this.description = "Displays co-ordinates on a slippy map.<br><br>Co-ordinates will be converted to decimal degrees before being shown on the map.<br><br>Supported formats:<ul><li>Degrees Minutes Seconds (DMS)</li><li>Degrees Decimal Minutes (DDM)</li><li>Decimal Degrees (DD)</li><li>Geohash</li><li>Military Grid Reference System (MGRS)</li><li>Ordnance Survey National Grid (OSNG)</li><li>Universal Transverse Mercator (UTM)</li></ul><br>This operation will not work offline.";
|
||||||
|
this.infoURL = "https://foundation.wikimedia.org/wiki/Maps_Terms_of_Use";
|
||||||
|
this.inputType = "string";
|
||||||
|
this.outputType = "string";
|
||||||
|
this.presentType = "html";
|
||||||
|
this.args = [
|
||||||
|
{
|
||||||
|
name: "Zoom Level",
|
||||||
|
type: "number",
|
||||||
|
value: 13
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Input Format",
|
||||||
|
type: "option",
|
||||||
|
value: ["Auto"].concat(FORMATS)
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Input Delimiter",
|
||||||
|
type: "option",
|
||||||
|
value: [
|
||||||
|
"Auto",
|
||||||
|
"Direction Preceding",
|
||||||
|
"Direction Following",
|
||||||
|
"\\n",
|
||||||
|
"Comma",
|
||||||
|
"Semi-colon",
|
||||||
|
"Colon"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} input
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
run(input, args) {
|
||||||
|
if (input.replace(/\s+/g, "") !== "") {
|
||||||
|
const inFormat = args[1],
|
||||||
|
inDelim = args[2];
|
||||||
|
let latLong;
|
||||||
|
try {
|
||||||
|
latLong = convertCoordinates(input, inFormat, inDelim, "Decimal Degrees", "Comma", "None", 5);
|
||||||
|
} catch (error) {
|
||||||
|
throw new OperationError(error);
|
||||||
|
}
|
||||||
|
latLong = latLong.replace(/[,]$/, "");
|
||||||
|
latLong = latLong.replace(/°/g, "");
|
||||||
|
return latLong;
|
||||||
|
}
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} data
|
||||||
|
* @param {Object[]} args
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
async present(data, args) {
|
||||||
|
if (data.replace(/\s+/g, "") === "") {
|
||||||
|
data = "0, 0";
|
||||||
|
}
|
||||||
|
const zoomLevel = args[0];
|
||||||
|
const tileUrl = "https://maps.wikimedia.org/osm-intl/{z}/{x}/{y}.png",
|
||||||
|
tileAttribution = "<a href=\"https://wikimediafoundation.org/wiki/Maps_Terms_of_Use\">Wikimedia maps</a> | © <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a> contributors",
|
||||||
|
leafletUrl = "https://unpkg.com/leaflet@1.5.0/dist/leaflet.js",
|
||||||
|
leafletCssUrl = "https://unpkg.com/leaflet@1.5.0/dist/leaflet.css";
|
||||||
|
return `<link rel="stylesheet" href="${leafletCssUrl}" crossorigin=""/>
|
||||||
|
<style>#output-html { white-space: normal; padding: 0; }</style>
|
||||||
|
<div id="presentedMap" style="width: 100%; height: 100%;"></div>
|
||||||
|
<script type="text/javascript">
|
||||||
|
var mapscript = document.createElement('script');
|
||||||
|
document.body.appendChild(mapscript);
|
||||||
|
mapscript.onload = function() {
|
||||||
|
var presentMap = L.map('presentedMap').setView([${data}], ${zoomLevel});
|
||||||
|
L.tileLayer('${tileUrl}', {
|
||||||
|
attribution: '${tileAttribution}'
|
||||||
|
}).addTo(presentMap);
|
||||||
|
|
||||||
|
L.marker([${data}]).addTo(presentMap)
|
||||||
|
.bindPopup('${data}')
|
||||||
|
.openPopup();
|
||||||
|
};
|
||||||
|
mapscript.src = "${leafletUrl}";
|
||||||
|
</script>`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ShowOnMap;
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Utils from "../core/Utils";
|
import Utils, { debounce } from "../core/Utils";
|
||||||
import {fromBase64} from "../core/lib/Base64";
|
import {fromBase64} from "../core/lib/Base64";
|
||||||
import Manager from "./Manager";
|
import Manager from "./Manager";
|
||||||
import HTMLCategory from "./HTMLCategory";
|
import HTMLCategory from "./HTMLCategory";
|
||||||
@@ -41,7 +41,6 @@ class App {
|
|||||||
this.autoBakePause = false;
|
this.autoBakePause = false;
|
||||||
this.progress = 0;
|
this.progress = 0;
|
||||||
this.ingId = 0;
|
this.ingId = 0;
|
||||||
this.timeouts = {};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -295,7 +294,7 @@ class App {
|
|||||||
minSize: minimise ? [0, 0, 0] : [240, 310, 450],
|
minSize: minimise ? [0, 0, 0] : [240, 310, 450],
|
||||||
gutterSize: 4,
|
gutterSize: 4,
|
||||||
expandToMin: true,
|
expandToMin: true,
|
||||||
onDrag: this.debounce(function() {
|
onDrag: debounce(function() {
|
||||||
this.manager.recipe.adjustWidth();
|
this.manager.recipe.adjustWidth();
|
||||||
this.manager.input.calcMaxTabs();
|
this.manager.input.calcMaxTabs();
|
||||||
this.manager.output.calcMaxTabs();
|
this.manager.output.calcMaxTabs();
|
||||||
@@ -723,6 +722,7 @@ class App {
|
|||||||
this.updateTitle(false, null, true);
|
this.updateTitle(false, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the page title to contain the new recipe
|
* Update the page title to contain the new recipe
|
||||||
*
|
*
|
||||||
@@ -766,29 +766,6 @@ class App {
|
|||||||
this.loadURIParams();
|
this.loadURIParams();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Debouncer to stop functions from being executed multiple times in a
|
|
||||||
* short space of time
|
|
||||||
* https://davidwalsh.name/javascript-debounce-function
|
|
||||||
*
|
|
||||||
* @param {function} func - The function to be executed after the debounce time
|
|
||||||
* @param {number} wait - The time (ms) to wait before executing the function
|
|
||||||
* @param {string} id - Unique ID to reference the timeout for the function
|
|
||||||
* @param {object} scope - The object to bind to the debounced function
|
|
||||||
* @param {array} args - Array of arguments to be passed to func
|
|
||||||
* @returns {function}
|
|
||||||
*/
|
|
||||||
debounce(func, wait, id, scope, args) {
|
|
||||||
return function() {
|
|
||||||
const later = function() {
|
|
||||||
func.apply(scope, args);
|
|
||||||
};
|
|
||||||
clearTimeout(this.timeouts[id]);
|
|
||||||
this.timeouts[id] = setTimeout(later, wait);
|
|
||||||
}.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ div#output {
|
|||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
#operations {
|
#operations.split {
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ChefWorker from "worker-loader?inline&fallback=false!../../core/ChefWorker";
|
import ChefWorker from "worker-loader?inline&fallback=false!../../core/ChefWorker.js";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waiter to handle conversations with a ChefWorker in the background.
|
* Waiter to handle conversations with a ChefWorker in the background.
|
||||||
|
|||||||
@@ -5,9 +5,9 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import LoaderWorker from "worker-loader?inline&fallback=false!../workers/LoaderWorker";
|
import LoaderWorker from "worker-loader?inline&fallback=false!../workers/LoaderWorker.js";
|
||||||
import InputWorker from "worker-loader?inline&fallback=false!../workers/InputWorker";
|
import InputWorker from "worker-loader?inline&fallback=false!../workers/InputWorker.mjs";
|
||||||
import Utils from "../../core/Utils.mjs";
|
import Utils, { debounce } from "../../core/Utils.mjs";
|
||||||
import { toBase64 } from "../../core/lib/Base64.mjs";
|
import { toBase64 } from "../../core/lib/Base64.mjs";
|
||||||
import { isImage } from "../../core/lib/FileType.mjs";
|
import { isImage } from "../../core/lib/FileType.mjs";
|
||||||
|
|
||||||
@@ -270,7 +270,7 @@ class InputWaiter {
|
|||||||
this.showLoadingInfo(r.data, true);
|
this.showLoadingInfo(r.data, true);
|
||||||
break;
|
break;
|
||||||
case "setInput":
|
case "setInput":
|
||||||
this.app.debounce(this.set, 50, "setInput", this, [r.data.inputObj, r.data.silent])();
|
debounce(this.set, 50, "setInput", this, [r.data.inputObj, r.data.silent])();
|
||||||
break;
|
break;
|
||||||
case "inputAdded":
|
case "inputAdded":
|
||||||
this.inputAdded(r.data.changeTab, r.data.inputNum);
|
this.inputAdded(r.data.changeTab, r.data.inputNum);
|
||||||
@@ -316,7 +316,7 @@ class InputWaiter {
|
|||||||
*/
|
*/
|
||||||
bakeAll() {
|
bakeAll() {
|
||||||
this.app.progress = 0;
|
this.app.progress = 0;
|
||||||
this.app.debounce(this.manager.controls.toggleBakeButtonFunction, 20, "toggleBakeButton", this, ["loading"]);
|
debounce(this.manager.controls.toggleBakeButtonFunction, 20, "toggleBakeButton", this, ["loading"]);
|
||||||
this.inputWorker.postMessage({
|
this.inputWorker.postMessage({
|
||||||
action: "bakeAll"
|
action: "bakeAll"
|
||||||
});
|
});
|
||||||
@@ -681,7 +681,7 @@ class InputWaiter {
|
|||||||
* @param {event} e
|
* @param {event} e
|
||||||
*/
|
*/
|
||||||
debounceInputChange(e) {
|
debounceInputChange(e) {
|
||||||
this.app.debounce(this.inputChange, 50, "inputChange", this, [e])();
|
debounce(this.inputChange, 50, "inputChange", this, [e])();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,10 +5,10 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Utils from "../../core/Utils.mjs";
|
import Utils, { debounce } from "../../core/Utils.mjs";
|
||||||
import Dish from "../../core/Dish.mjs";
|
import Dish from "../../core/Dish.mjs";
|
||||||
import FileSaver from "file-saver";
|
import FileSaver from "file-saver";
|
||||||
import ZipWorker from "worker-loader?inline&fallback=false!../workers/ZipWorker";
|
import ZipWorker from "worker-loader?inline&fallback=false!../workers/ZipWorker.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waiter to handle events related to the output
|
* Waiter to handle events related to the output
|
||||||
@@ -369,7 +369,7 @@ class OutputWaiter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.setOutputInfo(length, lines, output.data.duration);
|
this.setOutputInfo(length, lines, output.data.duration);
|
||||||
this.backgroundMagic();
|
debounce(this.backgroundMagic, 50, "backgroundMagic", this, [])();
|
||||||
}
|
}
|
||||||
}.bind(this));
|
}.bind(this));
|
||||||
}
|
}
|
||||||
@@ -717,7 +717,7 @@ class OutputWaiter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.app.debounce(this.set, 50, "setOutput", this, [inputNum])();
|
debounce(this.set, 50, "setOutput", this, [inputNum])();
|
||||||
|
|
||||||
document.getElementById("output-html").scroll(0, 0);
|
document.getElementById("output-html").scroll(0, 0);
|
||||||
document.getElementById("output-text").scroll(0, 0);
|
document.getElementById("output-text").scroll(0, 0);
|
||||||
|
|||||||
@@ -4,6 +4,8 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { debounce } from "../../core/Utils.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waiter to handle events related to the window object.
|
* Waiter to handle events related to the window object.
|
||||||
*/
|
*/
|
||||||
@@ -25,7 +27,7 @@ class WindowWaiter {
|
|||||||
* continuous resetting).
|
* continuous resetting).
|
||||||
*/
|
*/
|
||||||
windowResize() {
|
windowResize() {
|
||||||
this.app.debounce(this.app.resetLayout, 200, "windowResize", this.app, [])();
|
debounce(this.app.resetLayout, 200, "windowResize", this.app, [])();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,9 @@
|
|||||||
* @license Apache-2.0
|
* @license Apache-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import ChefWorker from "worker-loader?inline&fallback=false!../../core/ChefWorker";
|
import ChefWorker from "worker-loader?inline&fallback=false!../../core/ChefWorker.js";
|
||||||
import DishWorker from "worker-loader?inline&fallback=false!../workers/DishWorker";
|
import DishWorker from "worker-loader?inline&fallback=false!../workers/DishWorker.mjs";
|
||||||
|
import { debounce } from "../../core/Utils.mjs";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Waiter to handle conversations with the ChefWorker
|
* Waiter to handle conversations with the ChefWorker
|
||||||
@@ -281,7 +282,7 @@ class WorkerWaiter {
|
|||||||
*/
|
*/
|
||||||
setBakingStatus(bakingStatus) {
|
setBakingStatus(bakingStatus) {
|
||||||
this.app.baking = bakingStatus;
|
this.app.baking = bakingStatus;
|
||||||
this.app.debounce(this.manager.controls.toggleBakeButtonFunction, 20, "toggleBakeButton", this, [bakingStatus ? "cancel" : "bake"])();
|
debounce(this.manager.controls.toggleBakeButtonFunction, 20, "toggleBakeButton", this, [bakingStatus ? "cancel" : "bake"])();
|
||||||
|
|
||||||
if (bakingStatus) this.manager.output.hideMagicButton();
|
if (bakingStatus) this.manager.output.hideMagicButton();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -75,7 +75,7 @@ module.exports = {
|
|||||||
// Confirm that it has been added to the recipe
|
// Confirm that it has been added to the recipe
|
||||||
browser
|
browser
|
||||||
.useCss()
|
.useCss()
|
||||||
.waitForElementVisible(op)
|
.waitForElementVisible(op, 100)
|
||||||
.expect.element(op).text.to.contain("To Hex");
|
.expect.element(op).text.to.contain("To Hex");
|
||||||
|
|
||||||
// Enter input
|
// Enter input
|
||||||
@@ -107,6 +107,10 @@ module.exports = {
|
|||||||
loadOp("BSON deserialise", browser)
|
loadOp("BSON deserialise", browser)
|
||||||
.waitForElementNotVisible("#output-loader", 5000);
|
.waitForElementNotVisible("#output-loader", 5000);
|
||||||
|
|
||||||
|
// Charts
|
||||||
|
loadOp("Entropy", browser)
|
||||||
|
.waitForElementNotVisible("#output-loader", 5000);
|
||||||
|
|
||||||
// Ciphers
|
// Ciphers
|
||||||
loadOp("AES Encrypt", browser)
|
loadOp("AES Encrypt", browser)
|
||||||
.waitForElementNotVisible("#output-loader", 5000);
|
.waitForElementNotVisible("#output-loader", 5000);
|
||||||
@@ -135,6 +139,10 @@ module.exports = {
|
|||||||
loadOp("Encode text", browser)
|
loadOp("Encode text", browser)
|
||||||
.waitForElementNotVisible("#output-loader", 5000);
|
.waitForElementNotVisible("#output-loader", 5000);
|
||||||
|
|
||||||
|
// Hashing
|
||||||
|
loadOp("Streebog", browser)
|
||||||
|
.waitForElementNotVisible("#output-loader", 5000);
|
||||||
|
|
||||||
// Image
|
// Image
|
||||||
loadOp("Extract EXIF", browser)
|
loadOp("Extract EXIF", browser)
|
||||||
.waitForElementNotVisible("#output-loader", 5000);
|
.waitForElementNotVisible("#output-loader", 5000);
|
||||||
@@ -162,6 +170,54 @@ module.exports = {
|
|||||||
// UserAgent
|
// UserAgent
|
||||||
loadOp("Parse User Agent", browser)
|
loadOp("Parse User Agent", browser)
|
||||||
.waitForElementNotVisible("#output-loader", 5000);
|
.waitForElementNotVisible("#output-loader", 5000);
|
||||||
|
|
||||||
|
// YARA
|
||||||
|
loadOp("YARA Rules", browser)
|
||||||
|
.waitForElementNotVisible("#output-loader", 5000);
|
||||||
|
|
||||||
|
browser.click("#clr-recipe");
|
||||||
|
},
|
||||||
|
|
||||||
|
"Move around the UI": browser => {
|
||||||
|
const otherCat = "//a[contains(@class, 'category-title') and contains(@data-target, '#catOther')]",
|
||||||
|
genUUID = "//li[contains(@class, 'operation') and text()='Generate UUID']";
|
||||||
|
|
||||||
|
browser.useXpath();
|
||||||
|
|
||||||
|
// Scroll to a lower category
|
||||||
|
browser
|
||||||
|
.getLocationInView(otherCat)
|
||||||
|
.expect.element(otherCat).to.be.visible;
|
||||||
|
|
||||||
|
// Open category
|
||||||
|
browser
|
||||||
|
.click(otherCat)
|
||||||
|
.expect.element(genUUID).to.be.visible;
|
||||||
|
|
||||||
|
// Add op to recipe
|
||||||
|
/* mouseButtonUp drops wherever the actual cursor is, not necessarily in the right place,
|
||||||
|
so we can't test Sortable.js properly using Nightwatch. html-dnd doesn't work either.
|
||||||
|
Instead of relying on drag and drop, we double click on the op to load it. */
|
||||||
|
browser
|
||||||
|
.getLocationInView(genUUID)
|
||||||
|
.moveToElement(genUUID, 10, 10)
|
||||||
|
.doubleClick()
|
||||||
|
.useCss()
|
||||||
|
.waitForElementVisible(".operation .op-title", 1000)
|
||||||
|
.waitForElementNotVisible("#stale-indicator", 1000)
|
||||||
|
.expect.element("#output-text").to.have.value.which.matches(/[\da-f-]{36}/);
|
||||||
|
|
||||||
|
browser.click("#clr-recipe");
|
||||||
|
},
|
||||||
|
|
||||||
|
"Search": browser => {
|
||||||
|
// Search for an op
|
||||||
|
browser
|
||||||
|
.useCss()
|
||||||
|
.clearValue("#search")
|
||||||
|
.setValue("#search", "md5")
|
||||||
|
.useXpath()
|
||||||
|
.waitForElementVisible("//ul[@id='search-results']//u[text()='MD5']", 1000);
|
||||||
},
|
},
|
||||||
|
|
||||||
after: browser => {
|
after: browser => {
|
||||||
|
|||||||
Reference in New Issue
Block a user