mirror of
https://github.com/gchq/CyberChef.git
synced 2025-04-21 15:26:16 -04:00
Merged ESM into feature-bootstrap4
This commit is contained in:
commit
27b0505ede
96 changed files with 3814 additions and 15668 deletions
156
src/web/BackgroundWorkerWaiter.mjs
Normal file
156
src/web/BackgroundWorkerWaiter.mjs
Normal file
|
@ -0,0 +1,156 @@
|
|||
/**
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import ChefWorker from "worker-loader?inline&fallback=false!../core/ChefWorker";
|
||||
|
||||
/**
|
||||
* Waiter to handle conversations with a ChefWorker in the background.
|
||||
*/
|
||||
class BackgroundWorkerWaiter {
|
||||
|
||||
/**
|
||||
* BackgroundWorkerWaiter constructor.
|
||||
*
|
||||
* @param {App} app - The main view object for CyberChef.
|
||||
* @param {Manager} manager - The CyberChef event manager.
|
||||
*/
|
||||
constructor(app, manager) {
|
||||
this.app = app;
|
||||
this.manager = manager;
|
||||
|
||||
this.callbacks = {};
|
||||
this.callbackID = 0;
|
||||
this.completedCallback = -1;
|
||||
this.timeout = null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sets up the ChefWorker and associated listeners.
|
||||
*/
|
||||
registerChefWorker() {
|
||||
log.debug("Registering new background ChefWorker");
|
||||
this.chefWorker = new ChefWorker();
|
||||
this.chefWorker.addEventListener("message", this.handleChefMessage.bind(this));
|
||||
|
||||
let docURL = document.location.href.split(/[#?]/)[0];
|
||||
const index = docURL.lastIndexOf("/");
|
||||
if (index > 0) {
|
||||
docURL = docURL.substring(0, index);
|
||||
}
|
||||
this.chefWorker.postMessage({"action": "docURL", "data": docURL});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for messages sent back by the ChefWorker.
|
||||
*
|
||||
* @param {MessageEvent} e
|
||||
*/
|
||||
handleChefMessage(e) {
|
||||
const r = e.data;
|
||||
log.debug("Receiving '" + r.action + "' from ChefWorker in the background");
|
||||
|
||||
switch (r.action) {
|
||||
case "bakeComplete":
|
||||
case "bakeError":
|
||||
if (typeof r.data.id !== "undefined") {
|
||||
clearTimeout(this.timeout);
|
||||
this.callbacks[r.data.id].bind(this)(r.data);
|
||||
this.completedCallback = r.data.id;
|
||||
}
|
||||
break;
|
||||
case "workerLoaded":
|
||||
log.debug("Background ChefWorker loaded");
|
||||
break;
|
||||
case "optionUpdate":
|
||||
// Ignore these messages
|
||||
break;
|
||||
default:
|
||||
log.error("Unrecognised message from background ChefWorker", e);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Cancels the current bake by terminating the ChefWorker and creating a new one.
|
||||
*/
|
||||
cancelBake() {
|
||||
if (this.chefWorker)
|
||||
this.chefWorker.terminate();
|
||||
this.registerChefWorker();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Asks the ChefWorker to bake the input using the specified recipe.
|
||||
*
|
||||
* @param {string} input
|
||||
* @param {Object[]} recipeConfig
|
||||
* @param {Object} options
|
||||
* @param {number} progress
|
||||
* @param {boolean} step
|
||||
* @param {Function} callback
|
||||
*/
|
||||
bake(input, recipeConfig, options, progress, step, callback) {
|
||||
const id = this.callbackID++;
|
||||
this.callbacks[id] = callback;
|
||||
|
||||
this.chefWorker.postMessage({
|
||||
action: "bake",
|
||||
data: {
|
||||
input: input,
|
||||
recipeConfig: recipeConfig,
|
||||
options: options,
|
||||
progress: progress,
|
||||
step: step,
|
||||
id: id
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Asks the Magic operation what it can do with the input data.
|
||||
*
|
||||
* @param {string|ArrayBuffer} input
|
||||
*/
|
||||
magic(input) {
|
||||
// If we're still working on the previous bake, cancel it before stating a new one.
|
||||
if (this.completedCallback + 1 < this.callbackID) {
|
||||
clearTimeout(this.timeout);
|
||||
this.cancelBake();
|
||||
}
|
||||
|
||||
this.bake(input, [
|
||||
{
|
||||
"op": "Magic",
|
||||
"args": [3, false, false]
|
||||
}
|
||||
], {}, 0, false, this.magicComplete);
|
||||
|
||||
// Cancel this bake if it takes too long.
|
||||
this.timeout = setTimeout(this.cancelBake.bind(this), 3000);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handler for completed Magic bakes.
|
||||
*
|
||||
* @param {Object} response
|
||||
*/
|
||||
magicComplete(response) {
|
||||
log.debug("--- Background Magic Bake complete ---");
|
||||
if (!response || response.error) return;
|
||||
|
||||
this.manager.output.backgroundMagicResult(response.dish.value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
export default BackgroundWorkerWaiter;
|
|
@ -15,6 +15,7 @@ import OptionsWaiter from "./OptionsWaiter";
|
|||
import HighlighterWaiter from "./HighlighterWaiter";
|
||||
import SeasonalWaiter from "./SeasonalWaiter";
|
||||
import BindingsWaiter from "./BindingsWaiter";
|
||||
import BackgroundWorkerWaiter from "./BackgroundWorkerWaiter";
|
||||
|
||||
|
||||
/**
|
||||
|
@ -68,6 +69,7 @@ class Manager {
|
|||
this.highlighter = new HighlighterWaiter(this.app, this);
|
||||
this.seasonal = new SeasonalWaiter(this.app, this);
|
||||
this.bindings = new BindingsWaiter(this.app, this);
|
||||
this.background = new BackgroundWorkerWaiter(this.app, this);
|
||||
|
||||
// Object to store dynamic handlers to fire on elements that may not exist yet
|
||||
this.dynamicHandlers = {};
|
||||
|
@ -85,6 +87,7 @@ class Manager {
|
|||
this.controls.initComponents();
|
||||
this.controls.autoBakeChange();
|
||||
this.bindings.updateKeybList();
|
||||
this.background.registerChefWorker();
|
||||
this.seasonal.load();
|
||||
}
|
||||
|
||||
|
|
|
@ -117,6 +117,7 @@ class OutputWaiter {
|
|||
|
||||
this.manager.highlighter.removeHighlights();
|
||||
this.setOutputInfo(length, lines, duration);
|
||||
this.backgroundMagic();
|
||||
}
|
||||
|
||||
|
||||
|
@ -416,6 +417,42 @@ class OutputWaiter {
|
|||
return this.dishBuffer;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Triggers the BackgroundWorker to attempt Magic on the current output.
|
||||
*/
|
||||
backgroundMagic() {
|
||||
const sample = this.dishStr ? this.dishStr.slice(0, 1000) :
|
||||
this.dishBuffer ? this.dishBuffer.slice(0, 1000) : "";
|
||||
|
||||
if (sample.length) {
|
||||
this.manager.background.magic(sample);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handles the results of a background Magic call.
|
||||
*
|
||||
* @param {Object[]} options
|
||||
*/
|
||||
backgroundMagicResult(options) {
|
||||
if (!options.length ||
|
||||
!options[0].recipe.length)
|
||||
return;
|
||||
|
||||
//console.log(options);
|
||||
|
||||
const currentRecipeConfig = this.app.getRecipeConfig();
|
||||
const newRecipeConfig = currentRecipeConfig.concat(options[0].recipe);
|
||||
const recipeURL = "#recipe=" + Utils.encodeURIFragment(Utils.generatePrettyRecipe(newRecipeConfig));
|
||||
const opSequence = options[0].recipe.map(o => o.op).join(", ");
|
||||
|
||||
log.log(`Running <a href="${recipeURL}">${opSequence}</a> will result in "${Utils.truncate(options[0].data, 20)}"`);
|
||||
//this.app.setRecipeConfig(newRecipeConfig);
|
||||
//this.app.autoBake();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default OutputWaiter;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue