mirror of
https://github.com/gchq/CyberChef.git
synced 2025-06-17 03:35:07 -04:00
Merge branch 'master' into feature-threading
This commit is contained in:
commit
e977a1006c
45 changed files with 3426 additions and 2588 deletions
|
@ -266,13 +266,7 @@ App.prototype.silentBake = function() {
|
|||
* @returns {string}
|
||||
*/
|
||||
App.prototype.getInput = function() {
|
||||
const input = this.manager.input.get();
|
||||
|
||||
// Save to session storage in case we need to restore it later
|
||||
sessionStorage.setItem("inputLength", input.length);
|
||||
sessionStorage.setItem("input", input);
|
||||
|
||||
return input;
|
||||
return this.manager.input.get();
|
||||
};
|
||||
|
||||
|
||||
|
@ -282,8 +276,6 @@ App.prototype.getInput = function() {
|
|||
* @param {string} input - The string to set the input to
|
||||
*/
|
||||
App.prototype.setInput = function(input) {
|
||||
sessionStorage.setItem("inputLength", input.length);
|
||||
sessionStorage.setItem("input", input);
|
||||
this.manager.input.set(input);
|
||||
};
|
||||
|
||||
|
@ -466,7 +458,12 @@ App.prototype.addFavourite = function(name) {
|
|||
*/
|
||||
App.prototype.loadURIParams = function() {
|
||||
// Load query string or hash from URI (depending on which is populated)
|
||||
const params = window.location.search || window.location.hash;
|
||||
// We prefer getting the hash by splitting the href rather than referencing
|
||||
// location.hash as some browsers (Firefox) automatically URL decode it,
|
||||
// which cause issues.
|
||||
const params = window.location.search ||
|
||||
window.location.href.split("#")[1] ||
|
||||
window.location.hash;
|
||||
this.uriParams = Utils.parseURIParams(params);
|
||||
|
||||
// Pause auto-bake while loading but don't modify `this.autoBake_`
|
||||
|
@ -529,9 +526,7 @@ App.prototype.nextIngId = function() {
|
|||
* @returns {Object[]}
|
||||
*/
|
||||
App.prototype.getRecipeConfig = function() {
|
||||
const recipeConfig = this.manager.recipe.getConfig();
|
||||
sessionStorage.setItem("recipeConfig", JSON.stringify(recipeConfig));
|
||||
return recipeConfig;
|
||||
return this.manager.recipe.getConfig();
|
||||
};
|
||||
|
||||
|
||||
|
@ -541,7 +536,6 @@ App.prototype.getRecipeConfig = function() {
|
|||
* @param {Object[]} recipeConfig - The recipe configuration
|
||||
*/
|
||||
App.prototype.setRecipeConfig = function(recipeConfig) {
|
||||
sessionStorage.setItem("recipeConfig", JSON.stringify(recipeConfig));
|
||||
document.getElementById("rec-list").innerHTML = null;
|
||||
|
||||
for (let i = 0; i < recipeConfig.length; i++) {
|
||||
|
@ -596,15 +590,24 @@ App.prototype.resetLayout = function() {
|
|||
App.prototype.setCompileMessage = function() {
|
||||
// Display time since last build and compile message
|
||||
let now = new Date(),
|
||||
timeSinceCompile = Utils.fuzzyTime(now.getTime() - window.compileTime),
|
||||
compileInfo = "<span style=\"font-weight: normal\">Last build: " +
|
||||
timeSinceCompile.substr(0, 1).toUpperCase() + timeSinceCompile.substr(1) + " ago";
|
||||
timeSinceCompile = Utils.fuzzyTime(now.getTime() - window.compileTime);
|
||||
|
||||
// Calculate previous version to compare to
|
||||
let prev = PKG_VERSION.split(".").map(n => {
|
||||
return parseInt(n, 10);
|
||||
});
|
||||
if (prev[2] > 0) prev[2]--;
|
||||
else if (prev[1] > 0) prev[1]--;
|
||||
else prev[0]--;
|
||||
|
||||
const compareURL = `https://github.com/gchq/CyberChef/compare/v${prev.join(".")}...v${PKG_VERSION}`;
|
||||
|
||||
let compileInfo = `<a href='${compareURL}'>Last build: ${timeSinceCompile.substr(0, 1).toUpperCase() + timeSinceCompile.substr(1)} ago</a>`;
|
||||
|
||||
if (window.compileMessage !== "") {
|
||||
compileInfo += " - " + window.compileMessage;
|
||||
}
|
||||
|
||||
compileInfo += "</span>";
|
||||
document.getElementById("notice").innerHTML = compileInfo;
|
||||
};
|
||||
|
||||
|
@ -729,10 +732,20 @@ App.prototype.alertCloseClick = function() {
|
|||
App.prototype.stateChange = function(e) {
|
||||
this.autoBake();
|
||||
|
||||
// Set title
|
||||
const recipeConfig = this.getRecipeConfig();
|
||||
let title = "CyberChef";
|
||||
if (recipeConfig.length === 1) {
|
||||
title = `${recipeConfig[0].op} - ${title}`;
|
||||
} else if (recipeConfig.length > 1) {
|
||||
title = `${recipeConfig.length} operations - ${title}`;
|
||||
}
|
||||
document.title = title;
|
||||
|
||||
// Update the current history state (not creating a new one)
|
||||
if (this.options.updateUrl) {
|
||||
this.lastStateUrl = this.manager.controls.generateStateUrl(true, true);
|
||||
window.history.replaceState({}, "CyberChef", this.lastStateUrl);
|
||||
this.lastStateUrl = this.manager.controls.generateStateUrl(true, true, recipeConfig);
|
||||
window.history.replaceState({}, title, this.lastStateUrl);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -181,9 +181,9 @@ ControlsWaiter.prototype.generateStateUrl = function(includeRecipe, includeInput
|
|||
];
|
||||
|
||||
const hash = params
|
||||
.filter(v => v)
|
||||
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
|
||||
.join("&");
|
||||
.filter(v => v)
|
||||
.map(([key, value]) => `${key}=${encodeURIComponent(value)}`)
|
||||
.join("&");
|
||||
|
||||
if (hash) {
|
||||
return `${link}#${hash}`;
|
||||
|
@ -286,7 +286,7 @@ ControlsWaiter.prototype.populateLoadRecipesList = function() {
|
|||
|
||||
// Add recipes to select
|
||||
const savedRecipes = localStorage.savedRecipes ?
|
||||
JSON.parse(localStorage.savedRecipes) : [];
|
||||
JSON.parse(localStorage.savedRecipes) : [];
|
||||
|
||||
for (i = 0; i < savedRecipes.length; i++) {
|
||||
const opt = document.createElement("option");
|
||||
|
@ -308,7 +308,7 @@ ControlsWaiter.prototype.populateLoadRecipesList = function() {
|
|||
ControlsWaiter.prototype.loadDeleteClick = function() {
|
||||
const id = parseInt(document.getElementById("load-name").value, 10);
|
||||
const rawSavedRecipes = localStorage.savedRecipes ?
|
||||
JSON.parse(localStorage.savedRecipes) : [];
|
||||
JSON.parse(localStorage.savedRecipes) : [];
|
||||
|
||||
const savedRecipes = rawSavedRecipes.filter(r => r.id !== id);
|
||||
|
||||
|
@ -323,7 +323,7 @@ ControlsWaiter.prototype.loadDeleteClick = function() {
|
|||
ControlsWaiter.prototype.loadNameChange = function(e) {
|
||||
const el = e.target;
|
||||
const savedRecipes = localStorage.savedRecipes ?
|
||||
JSON.parse(localStorage.savedRecipes) : [];
|
||||
JSON.parse(localStorage.savedRecipes) : [];
|
||||
const id = parseInt(el.value, 10);
|
||||
|
||||
const recipe = savedRecipes.find(r => r.id === id);
|
||||
|
|
|
@ -493,13 +493,14 @@ HighlighterWaiter.prototype.highlight = function(textarea, highlighter, pos) {
|
|||
//if (colour) cssClass += "-"+colour;
|
||||
|
||||
// Remove HTML tags
|
||||
text = text.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/\n/g, " ")
|
||||
// Convert placeholders to tags
|
||||
.replace(startPlaceholderRegex, "<span class=\""+cssClass+"\">")
|
||||
.replace(endPlaceholderRegex, "</span>") + " ";
|
||||
text = text
|
||||
.replace(/&/g, "&")
|
||||
.replace(/</g, "<")
|
||||
.replace(/>/g, ">")
|
||||
.replace(/\n/g, " ")
|
||||
// Convert placeholders to tags
|
||||
.replace(startPlaceholderRegex, "<span class=\""+cssClass+"\">")
|
||||
.replace(endPlaceholderRegex, "</span>") + " ";
|
||||
|
||||
// Adjust width to allow for scrollbars
|
||||
highlighter.style.width = textarea.clientWidth + "px";
|
||||
|
|
|
@ -166,7 +166,7 @@ InputWaiter.prototype.inputDrop = function(e) {
|
|||
this.set(inputCharcode);
|
||||
const recipeConfig = this.app.getRecipeConfig();
|
||||
if (!recipeConfig[0] || recipeConfig[0].op !== "From Hex") {
|
||||
recipeConfig.unshift({op:"From Hex", args:["Space"]});
|
||||
recipeConfig.unshift({op: "From Hex", args: ["Space"]});
|
||||
this.app.setRecipeConfig(recipeConfig);
|
||||
}
|
||||
|
||||
|
|
|
@ -145,6 +145,7 @@ Manager.prototype.initialiseEventListeners = function() {
|
|||
document.getElementById("output-html").addEventListener("mousemove", this.highlighter.outputHtmlMousemove.bind(this.highlighter));
|
||||
this.addMultiEventListener("#output-text", "mousedown dblclick select", this.highlighter.outputMousedown, this.highlighter);
|
||||
this.addMultiEventListener("#output-html", "mousedown dblclick select", this.highlighter.outputHtmlMousedown, this.highlighter);
|
||||
this.addDynamicListener(".file-switch", "click", this.output.fileSwitch, this.output);
|
||||
|
||||
// Options
|
||||
document.getElementById("options").addEventListener("click", this.options.optionsClick.bind(this.options));
|
||||
|
|
|
@ -167,6 +167,17 @@ OutputWaiter.prototype.undoSwitchClick = function() {
|
|||
document.getElementById("undo-switch").disabled = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* Handler for file switch click events.
|
||||
* Moves a files data for items created via Utils.displayFilesAsHTML to the input.
|
||||
*/
|
||||
OutputWaiter.prototype.fileSwitch = function(e) {
|
||||
e.preventDefault();
|
||||
this.switchOrigData = this.manager.input.get();
|
||||
this.app.setInput(e.target.getAttribute("fileValue"));
|
||||
document.getElementById("undo-switch").disabled = false;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler for maximise output click events.
|
||||
|
|
|
@ -26,12 +26,14 @@
|
|||
<title>CyberChef</title>
|
||||
|
||||
<meta name="copyright" content="Crown Copyright 2016" />
|
||||
<meta name="description" content="The Cyber Swiss Army Knife" />
|
||||
<meta name="description" content="The Cyber Swiss Army Knife - a web app for encryption, encoding, compression and data analysis" />
|
||||
<meta name="keywords" content="base64, hex, decode, encode, encrypt, decrypt, compress, decompress, regex, regular expressions, hash, crypt, hexadecimal, user agent, url, certificate, x.509, parser, JSON, gzip, md5, sha1, aes, des, blowfish, xor" />
|
||||
|
||||
<link rel="icon" type="image/ico" href="<%- require('../static/images/favicon.ico') %>" />
|
||||
|
||||
<script type="application/javascript">
|
||||
"use strict";
|
||||
|
||||
// Load theme before the preloader is shown
|
||||
document.querySelector(":root").className = (JSON.parse(localStorage.getItem("options")) || {}).theme;
|
||||
|
||||
|
@ -72,6 +74,11 @@
|
|||
changeLoadingMsg();
|
||||
window.loadingMsgsInt = setInterval(changeLoadingMsg, (Math.random() * 1000) + 1000);
|
||||
</script>
|
||||
<% if (!htmlWebpackPlugin.options.inline) { %>
|
||||
<script type="application/ld+json">
|
||||
<% print(JSON.stringify(require("../static/structuredData.json"))); %>
|
||||
</script>
|
||||
<% } %>
|
||||
</head>
|
||||
<body>
|
||||
<!-- Preloader overlay -->
|
||||
|
@ -87,23 +94,29 @@
|
|||
</div>
|
||||
<div id="content-wrapper">
|
||||
<div id="banner">
|
||||
<% if (htmlWebpackPlugin.options.inline) { %>
|
||||
<span style="float: left; margin-left: 10px;">Compile time: <%= htmlWebpackPlugin.options.compileTime %></span>
|
||||
<% } else { %>
|
||||
<a href="cyberchef.htm" style="float: left; margin-left: 10px; margin-right: 80px;" download>Download CyberChef<img aria-hidden="true" src="<%- require('../static/images/download-24x24.png') %>" alt="Download Icon"/></a>
|
||||
<% } %>
|
||||
<span id="notice">
|
||||
<script type="text/javascript">
|
||||
// Must be text/javascript rather than application/javascript otherwise IE won't recognise it...
|
||||
if (navigator.userAgent && navigator.userAgent.match(/MSIE \d\d?\./)) {
|
||||
document.write("Internet Explorer is not supported, please use Firefox or Chrome instead");
|
||||
alert("Internet Explorer is not supported, please use Firefox or Chrome instead");
|
||||
}
|
||||
</script>
|
||||
<noscript>JavaScript is not enabled. Good luck.</noscript>
|
||||
</span>
|
||||
<a href="#" id="support" class="banner-right" data-toggle="modal" data-target="#support-modal">About / Support<img aria-hidden="true" src="<%- require('../static/images/help-22x22.png') %>" alt="Question Mark Icon"/></a>
|
||||
<a href="#" id="options" class="banner-right">Options<img aria-hidden="true" src="<%- require('../static/images/settings-22x22.png') %>" alt="Settings Icon"/></a>
|
||||
<div class="col-md-4" style="text-align: left; padding-left: 10px;">
|
||||
<% if (htmlWebpackPlugin.options.inline) { %>
|
||||
<span>Version <%= htmlWebpackPlugin.options.version %></span>
|
||||
<% } else { %>
|
||||
<a href="cyberchef.htm" download>Download CyberChef<img aria-hidden="true" src="<%- require('../static/images/download-24x24.png') %>" alt="Download Icon"/></a>
|
||||
<% } %>
|
||||
</div>
|
||||
<div class="col-md-4" style="text-align: center;">
|
||||
<span id="notice">
|
||||
<script type="text/javascript">
|
||||
// Must be text/javascript rather than application/javascript otherwise IE won't recognise it...
|
||||
if (navigator.userAgent && navigator.userAgent.match(/MSIE \d\d?\./)) {
|
||||
document.write("Internet Explorer is not supported, please use Firefox or Chrome instead");
|
||||
alert("Internet Explorer is not supported, please use Firefox or Chrome instead");
|
||||
}
|
||||
</script>
|
||||
<noscript>JavaScript is not enabled. Good luck.</noscript>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-md-4" style="text-align: right; padding-right: 0;">
|
||||
<a href="#" id="options">Options<img aria-hidden="true" src="<%- require('../static/images/settings-22x22.png') %>" alt="Settings Icon"/></a>
|
||||
<a href="#" id="support" data-toggle="modal" data-target="#support-modal">About / Support<img aria-hidden="true" src="<%- require('../static/images/help-22x22.png') %>" alt="Question Mark Icon"/></a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="workspace-wrapper">
|
||||
<div id="operations" class="split split-horizontal no-select">
|
||||
|
@ -266,32 +279,32 @@
|
|||
<label for="theme"> Theme (only supported in modern browsers)</label>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<input type="checkbox" option="update_url" id="update_url" checked />
|
||||
<label for="update_url"> Update the URL when the input or recipe changes </label>
|
||||
<input type="checkbox" option="updateUrl" id="updateUrl" checked />
|
||||
<label for="updateUrl"> Update the URL when the input or recipe changes </label>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<input type="checkbox" option="show_highlighter" id="show_highlighter" checked />
|
||||
<label for="show_highlighter"> Highlight selected bytes in output and input (when possible) </label>
|
||||
<input type="checkbox" option="showHighlighter" id="showHighlighter" checked />
|
||||
<label for="showHighlighter"> Highlight selected bytes in output and input (when possible) </label>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<input type="checkbox" option="treat_as_utf8" id="treat_as_utf8" checked />
|
||||
<label for="treat_as_utf8"> Treat output as UTF-8 if possible </label>
|
||||
<input type="checkbox" option="treatAsUtf8" id="treatAsUtf8" checked />
|
||||
<label for="treatAsUtf8"> Treat output as UTF-8 if possible </label>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<input type="checkbox" option="word_wrap" id="word_wrap" checked />
|
||||
<label for="word_wrap"> Word wrap the input and output </label>
|
||||
<input type="checkbox" option="wordWrap" id="wordWrap" checked />
|
||||
<label for="wordWrap"> Word wrap the input and output </label>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<input type="checkbox" option="show_errors" id="show_errors" checked />
|
||||
<label for="show_errors"> Operation error reporting (recommended) </label>
|
||||
<input type="checkbox" option="showErrors" id="showErrors" checked />
|
||||
<label for="showErrors"> Operation error reporting (recommended) </label>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<input type="number" option="error_timeout" id="error_timeout" />
|
||||
<label for="error_timeout"> Operation error timeout in ms (0 for never) </label>
|
||||
<input type="number" option="errorTimeout" id="errorTimeout" />
|
||||
<label for="errorTimeout"> Operation error timeout in ms (0 for never) </label>
|
||||
</div>
|
||||
<div class="option-item">
|
||||
<input type="number" option="auto_bake_threshold" id="auto_bake_threshold"/>
|
||||
<label for="auto_bake_threshold"> Auto Bake threshold in ms </label>
|
||||
<input type="number" option="autoBakeThreshold" id="autoBakeThreshold"/>
|
||||
<label for="autoBakeThreshold"> Auto Bake threshold in ms </label>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-footer">
|
||||
|
|
|
@ -38,15 +38,15 @@ function main() {
|
|||
];
|
||||
|
||||
const defaultOptions = {
|
||||
updateUrl : true,
|
||||
showHighlighter : true,
|
||||
treatAsUtf8 : true,
|
||||
wordWrap : true,
|
||||
showErrors : true,
|
||||
errorTimeout : 4000,
|
||||
autoBakeThreshold : 200,
|
||||
attemptHighlight : true,
|
||||
theme : "classic",
|
||||
updateUrl: true,
|
||||
showHighlighter: true,
|
||||
treatAsUtf8: true,
|
||||
wordWrap: true,
|
||||
showErrors: true,
|
||||
errorTimeout: 4000,
|
||||
autoBakeThreshold: 200,
|
||||
attemptHighlight: true,
|
||||
theme: "classic",
|
||||
};
|
||||
|
||||
document.removeEventListener("DOMContentLoaded", main, false);
|
||||
|
|
23
src/web/static/structuredData.json
Normal file
23
src/web/static/structuredData.json
Normal file
|
@ -0,0 +1,23 @@
|
|||
[
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
"@type": "Organization",
|
||||
"url": "https://gchq.github.io/CyberChef/",
|
||||
"logo": "https://gchq.github.io/CyberChef/images/cyberchef-128x128.png",
|
||||
"sameAs": [
|
||||
"https://github.com/gchq/CyberChef",
|
||||
"https://www.npmjs.com/package/cyberchef"
|
||||
]
|
||||
},
|
||||
{
|
||||
"@context": "http://schema.org",
|
||||
"@type": "WebSite",
|
||||
"url": "https://gchq.github.io/CyberChef/",
|
||||
"name": "CyberChef",
|
||||
"potentialAction": {
|
||||
"@type": "SearchAction",
|
||||
"target": "https://gchq.github.io/CyberChef/?op={operation_search_term}",
|
||||
"query-input": "required name=operation_search_term"
|
||||
}
|
||||
}
|
||||
]
|
|
@ -59,6 +59,7 @@
|
|||
background-color: var(--arg-background);
|
||||
border: 1px solid var(--arg-border-colour);
|
||||
font-family: var(--fixed-width-font-family);
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
.short-string {
|
||||
|
|
|
@ -10,19 +10,15 @@
|
|||
position: absolute;
|
||||
height: 30px;
|
||||
width: 100%;
|
||||
text-align: center;
|
||||
line-height: 30px;
|
||||
border-bottom: 1px solid var(--primary-border-colour);
|
||||
color: var(--banner-font-colour);
|
||||
background-color: var(--banner-bg-colour);
|
||||
}
|
||||
|
||||
.banner-right {
|
||||
float: right;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
#banner img {
|
||||
margin-bottom: 2px;
|
||||
margin-left: 8px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue