Compare commits

..

8 Commits

Author SHA1 Message Date
j433866
507c951f28 9.0.2 2019-07-24 09:12:16 +01:00
j433866
8a67103808 Merge branch 'artemisbot-bug/dark-mode' 2019-07-24 09:10:51 +01:00
Matt
b3a10d4f9e Made some better colour choices 2019-07-23 19:17:21 +01:00
Matt
d4c4e2599d Reduced redundancy 2019-07-22 23:16:17 +01:00
Matt
67ead1c250 Fixed alternative theme tables 2019-07-22 23:12:36 +01:00
j433866
897dc0fb97 9.0.1 2019-07-10 15:01:53 +01:00
j433866
a08419a4ce Remove getOutput function, use Dish object instead
Fix inputNum error in WorkerWaiter.
Replace explicit tab shadows with class lists
2019-07-10 14:58:07 +01:00
n1474335
710223d7de Updated CHANGELOG 2019-07-09 14:38:10 +01:00
12 changed files with 75 additions and 76 deletions

View File

@@ -3,10 +3,10 @@ All major and minor version changes will be documented in this file. Details of
## [9.0.0] - 2019-07-09
- [Multiple inputs](https://github.com/gchq/CyberChef/wiki/Multiple-Inputs) are now supported in the main web UI, allowing you to upload and process multiple files at once [@j433866] [#566]
- A [Node.js API](https://github.com/gchq/CyberChef/wiki/Node-API) has been implemented, meaning that CyberChef can now be used as a library, either to provide specific operations, or an entire baking environment [@d98762625] [#291]
- A [read-eval-print loop (REPL)](https://github.com/gchq/CyberChef/wiki/Node-API#repl) is also included to enable prototyping and experimentation with the API [@d98762625] [#291]
- Light and dark Solarized themes added [@j433866] [#566]
- [Multiple inputs](https://github.com/gchq/CyberChef/wiki/Multiple-Inputs) are now supported in the main web UI, allowing you to upload and process multiple files at once [@j433866] | [#566]
- A [Node.js API](https://github.com/gchq/CyberChef/wiki/Node-API) has been implemented, meaning that CyberChef can now be used as a library, either to provide specific operations, or an entire baking environment [@d98762625] | [#291]
- A [read-eval-print loop (REPL)](https://github.com/gchq/CyberChef/wiki/Node-API#repl) is also included to enable prototyping and experimentation with the API [@d98762625] | [#291]
- Light and dark Solarized themes added [@j433866] | [#566]
### [8.38.0] - 2019-07-03
- 'Streebog' and 'GOST hash' operations added [@MShwed] [@n1474335] | [#530]

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "9.0.0",
"version": "9.0.2",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "cyberchef",
"version": "9.0.0",
"version": "9.0.2",
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
"author": "n1474335 <n1474335@gmail.com>",
"homepage": "https://gchq.github.io/CyberChef",

View File

@@ -125,6 +125,7 @@
/* Misc. */
--drop-file-border-colour: #3a87ad;
--table-border-colour: #ccc;
--popover-background: #fff;
--popover-border-colour: #ccc;
--code-background: #f9f2f4;

View File

@@ -121,6 +121,7 @@
/* Misc. */
--drop-file-border-colour: #0e639c;
--table-border-colour: #555;
--popover-background: #444;
--popover-border-colour: #555;
--code-background: #0e639c;

View File

@@ -121,6 +121,7 @@
/* Misc. */
--drop-file-border-colour: purple;
--table-border-colour: var(--hl3);
--popover-background: turquoise;
--popover-border-colour: violet;
--code-background: black;

View File

@@ -138,6 +138,7 @@
/* Misc. */
--drop-file-border-colour: var(--base01);
--table-border-colour: var(--base01);
--popover-background: var(--base02);
--popover-border-colour: var(--base01);
--code-background: var(--base03);

View File

@@ -140,6 +140,7 @@
/* Misc. */
--drop-file-border-colour: var(--base1);
--table-border-colour: var(--base1);
--popover-background: var(--base2);
--popover-border-colour: var(--base1);
--code-background: var(--base3);

View File

@@ -148,6 +148,15 @@ optgroup {
width: auto !important;
}
.table,
.table-hover tbody tr:hover {
color: var(--primary-font-colour);
}
.table-bordered th, .table-bordered td {
border: 1px solid var(--table-border-colour);
}
.popover {
background-color: var(--popover-background);
border-color: var(--popover-border-colour);

View File

@@ -1111,7 +1111,7 @@ class InputWaiter {
});
} else if (numTabs === this.maxTabs) {
// Can't create a new tab
document.getElementById("input-tabs").lastElementChild.style.boxShadow = "-15px 0px 15px -15px var(--primary-border-colour) inset";
document.getElementById("input-tabs").lastElementChild.classList.add("tabs-right");
}
if (changeTab) this.changeTab(inputNum, false);

View File

@@ -6,6 +6,7 @@
*/
import Utils from "../../core/Utils.mjs";
import Dish from "../../core/Dish.mjs";
import FileSaver from "file-saver";
import ZipWorker from "worker-loader?inline&fallback=false!../workers/ZipWorker";
@@ -41,39 +42,6 @@ class OutputWaiter {
}
}
/**
* Gets the output for the specified input number
*
* @param {number} inputNum - The input to get the output for
* @param {boolean} [raw=true] - If true, returns the raw data instead of the presented result.
* @returns {string | ArrayBuffer}
*/
getOutput(inputNum, raw=true) {
if (!this.outputExists(inputNum)) return -1;
if (this.outputs[inputNum].data === null) return "";
if (raw) {
let data = this.outputs[inputNum].data.dish.value;
if (Array.isArray(data)) {
data = new Uint8Array(data.length);
for (let i = 0; i < data.length; i++) {
data[i] = this.outputs[inputNum].data.dish.value[i];
}
data = data.buffer;
} else if (typeof data !== "object" && typeof data !== "string") {
data = String(data);
}
return data;
} else if (typeof this.outputs[inputNum].data.result === "string") {
return this.outputs[inputNum].data.result;
} else {
return this.outputs[inputNum].data.result || "";
}
}
/**
* Gets the dish object for an output.
*
@@ -103,16 +71,6 @@ class OutputWaiter {
return true;
}
/**
* Gets the output string or FileBuffer for the active input
*
* @param {boolean} [raw=true] - If true, returns the raw data instead of the presented result.
* @returns {string | ArrayBuffer}
*/
getActive(raw=true) {
return this.getOutput(this.manager.tabs.getActiveOutputTab(), raw);
}
/**
* Adds a new output to the output array.
* Creates a new tab if we have less than maxtabs tabs open
@@ -152,6 +110,10 @@ class OutputWaiter {
this.addOutput(inputNum);
}
if (Object.prototype.hasOwnProperty.call(data, "dish")) {
data.dish = new Dish(data.dish);
}
this.outputs[inputNum].data = data;
const tabItem = this.manager.tabs.getOutputTabItem(inputNum);
@@ -267,13 +229,13 @@ class OutputWaiter {
* @param {number} inputNum
*/
async set(inputNum) {
if (inputNum !== this.manager.tabs.getActiveOutputTab()) return;
if (inputNum !== this.manager.tabs.getActiveOutputTab() ||
!this.outputExists(inputNum)) return;
this.toggleLoader(true);
return new Promise(async function(resolve, reject) {
const output = this.outputs[inputNum],
activeTab = this.manager.tabs.getActiveOutputTab();
if (output === undefined || output === null) return;
if (typeof inputNum !== "number") inputNum = parseInt(inputNum, 10);
const outputText = document.getElementById("output-text");
@@ -281,6 +243,7 @@ class OutputWaiter {
const outputFile = document.getElementById("output-file");
const outputHighlighter = document.getElementById("output-highlighter");
const inputHighlighter = document.getElementById("input-highlighter");
// If pending or baking, show loader and status message
// If error, style the tab and handle the error
// If done, display the output if it's the active tab
@@ -544,11 +507,17 @@ class OutputWaiter {
* Handler for file download events.
*/
async downloadFile() {
const dish = this.getOutputDish(this.manager.tabs.getActiveOutputTab());
if (dish === null) {
this.app.alert("Could not find any output data to download. Has this output been baked?", 3000);
return;
}
let fileName = window.prompt("Please enter a filename: ", "download.dat");
if (fileName === null) fileName = "download.dat";
const file = new File([this.getActive(true)], fileName);
const data = await dish.get(Dish.ARRAY_BUFFER),
file = new File([data], fileName);
FileSaver.saveAs(file, fileName, false);
}
@@ -684,7 +653,7 @@ class OutputWaiter {
tabsWrapper.appendChild(newTab);
} else if (numTabs === this.maxTabs) {
// Can't create a new tab
document.getElementById("output-tabs").lastElementChild.style.boxShadow = "-15px 0px 15px -15px var(--primary-border-colour) inset";
document.getElementById("output-tabs").lastElementChild.classList.add("tabs-right");
}
this.displayTabInfo(inputNum);
@@ -1039,8 +1008,8 @@ class OutputWaiter {
*/
async backgroundMagic() {
this.hideMagicButton();
if (!this.app.options.autoMagic || !this.getActive(true)) return;
const dish = this.outputs[this.manager.tabs.getActiveOutputTab()].data.dish;
const dish = this.getOutputDish(this.manager.tabs.getActiveOutputTab());
if (!this.app.options.autoMagic || dish === null) return;
const buffer = await this.getDishBuffer(dish);
const sample = buffer.slice(0, 1000) || "";
@@ -1181,12 +1150,14 @@ class OutputWaiter {
* Copies the output to the clipboard
*/
copyClick() {
let output = this.getActive(true);
if (typeof output !== "string") {
output = Utils.arrayBufferToStr(output);
const dish = this.getOutputDish(this.manager.tabs.getActiveOutputTab());
if (dish === null) {
this.app.alert("Could not find data to copy. Has this output been baked yet?", 3000);
return;
}
const output = dish.get(Dish.STRING);
// Create invisible textarea to populate with the raw dish string (not the printable version that
// contains dots instead of the actual bytes)
const textarea = document.createElement("textarea");
@@ -1223,8 +1194,14 @@ class OutputWaiter {
*
* @returns {boolean}
*/
containsCR() {
return this.getActive(false).indexOf("\r") >= 0;
async containsCR() {
const dish = this.getOutputDish(this.manager.tabs.getActiveOutputTab());
if (dish === null) return;
if (dish.type === Dish.STRING) {
const data = await dish.get(Dish.STRING);
return data.indexOf("\r") >= 0;
}
}
/**
@@ -1312,7 +1289,7 @@ class OutputWaiter {
/**
* Searches the outputs using the filter settings and displays the results
*/
filterTabSearch() {
async filterTabSearch() {
const showPending = document.getElementById("output-show-pending").checked,
showBaking = document.getElementById("output-show-baking").checked,
showBaked = document.getElementById("output-show-baked").checked,
@@ -1349,15 +1326,26 @@ class OutputWaiter {
"stale": "Stale (output is out of date)",
"inactive": "Not baked yet"
};
results.push({
inputNum: iNum,
textDisplay: outDisplay[output.status]
});
} else if (output.status === "baked" && showBaked && output.progress === false) {
let data = this.getOutput(iNum, false).slice(0, 4096);
if (typeof data !== "string") {
data = Utils.arrayBufferToStr(data);
// If the output has a dish object, check it against the filter
if (Object.prototype.hasOwnProperty.call(output, "data") &&
output.data &&
Object.prototype.hasOwnProperty.call(output.data, "dish")) {
const data = output.data.dish.get(Dish.STRING);
if (contentFilterExp.test(data)) {
results.push({
inputNum: iNum,
textDisplay: data.slice(0, 100)
});
}
} else {
results.push({
inputNum: iNum,
textDisplay: outDisplay[output.status]
});
}
} else if (output.status === "baked" && showBaked && output.progress === false) {
let data = await output.data.dish.get(Dish.STRING);
data = data.replace(/[\r\n]/g, "");
if (contentFilterExp.test(data)) {
results.push({
@@ -1366,10 +1354,7 @@ class OutputWaiter {
});
}
} else if (output.progress !== false && showErrored) {
let data = this.getOutput(iNum, false).slice(0, 4096);
if (typeof data !== "string") {
data = Utils.arrayBufferToStr(data);
}
let data = await output.data.dish.get(Dish.STRING);
data = data.replace(/[\r\n]/g, "");
if (contentFilterExp.test(data)) {
results.push({

View File

@@ -178,7 +178,7 @@ class WorkerWaiter {
let inputNum = 0;
log.debug(`Receiving ${r.action} from ChefWorker.`);
if ("inputNum" in r.data) {
if (Object.prototype.hasOwnProperty.call(r.data, "inputNum")) {
inputNum = r.data.inputNum;
}