mirror of
https://github.com/gchq/CyberChef.git
synced 2025-05-07 23:15:14 -04:00
parent
de3ef202d5
commit
c5a1b69c30
693 changed files with 26685 additions and 51240 deletions
|
@ -15,27 +15,16 @@ import fs from "fs";
|
|||
import path from "path";
|
||||
import EscapeString from "../../operations/EscapeString.mjs";
|
||||
|
||||
|
||||
const dir = path.join(process.cwd() + "/src/core/operations/");
|
||||
if (!fs.existsSync(dir)) {
|
||||
console.log("\nCWD: " + process.cwd());
|
||||
console.log("Error: newOperation.mjs should be run from the project root");
|
||||
console.log(
|
||||
"Example> node --experimental-modules src/core/config/scripts/newOperation.mjs",
|
||||
);
|
||||
console.log("Example> node --experimental-modules src/core/config/scripts/newOperation.mjs");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
const ioTypes = [
|
||||
"string",
|
||||
"byteArray",
|
||||
"number",
|
||||
"html",
|
||||
"ArrayBuffer",
|
||||
"BigNumber",
|
||||
"JSON",
|
||||
"File",
|
||||
"List<File>",
|
||||
];
|
||||
const ioTypes = ["string", "byteArray", "number", "html", "ArrayBuffer", "BigNumber", "JSON", "File", "List<File>"];
|
||||
|
||||
const schema = {
|
||||
properties: {
|
||||
|
@ -46,8 +35,7 @@ const schema = {
|
|||
type: "string",
|
||||
pattern: /^[\w\s-/().]+$/,
|
||||
required: true,
|
||||
message:
|
||||
"Operation names should consist of letters, numbers or the following symbols: _-/().",
|
||||
message: "Operation names should consist of letters, numbers or the following symbols: _-/()."
|
||||
},
|
||||
module: {
|
||||
description: `Modules are used to group operations that rely on large libraries. Any operation that is not in the Default module will be loaded in dynamically when it is first called. All operations in the same module will also be loaded at this time. This system prevents the CyberChef web app from getting too bloated and taking a long time to load initially.
|
||||
|
@ -56,89 +44,69 @@ If your operation does not rely on a library, just leave this blank and it will
|
|||
prompt: "Module",
|
||||
type: "string",
|
||||
pattern: /^[A-Z][A-Za-z\d]+$/,
|
||||
message:
|
||||
"Module names should start with a capital letter and not contain any spaces or symbols.",
|
||||
default: "Default",
|
||||
message: "Module names should start with a capital letter and not contain any spaces or symbols.",
|
||||
default: "Default"
|
||||
},
|
||||
description: {
|
||||
description:
|
||||
"The description should explain what the operation is and how it works. It can describe how the arguments should be entered and give examples of expected input and output. HTML markup is supported. Use <code> tags for examples. The description is scanned during searches, so include terms that are likely to be searched for when someone is looking for your operation.",
|
||||
example:
|
||||
"Converts URI/URL percent-encoded characters back to their raw values.<br><br>e.g. <code>%3d</code> becomes <code>=</code>",
|
||||
description: "The description should explain what the operation is and how it works. It can describe how the arguments should be entered and give examples of expected input and output. HTML markup is supported. Use <code> tags for examples. The description is scanned during searches, so include terms that are likely to be searched for when someone is looking for your operation.",
|
||||
example: "Converts URI/URL percent-encoded characters back to their raw values.<br><br>e.g. <code>%3d</code> becomes <code>=</code>",
|
||||
prompt: "Description",
|
||||
type: "string",
|
||||
type: "string"
|
||||
},
|
||||
infoURL: {
|
||||
description:
|
||||
"An optional URL for an external site can be added to give more information about the operation. Wikipedia links are often suitable. If linking to Wikipedia, use an international link (e.g. https://wikipedia.org/...) rather than a localised link (e.g. https://en.wikipedia.org/...).",
|
||||
description: "An optional URL for an external site can be added to give more information about the operation. Wikipedia links are often suitable. If linking to Wikipedia, use an international link (e.g. https://wikipedia.org/...) rather than a localised link (e.g. https://en.wikipedia.org/...).",
|
||||
example: "https://wikipedia.org/wiki/Percent-encoding",
|
||||
prompt: "Information URL",
|
||||
type: "string",
|
||||
},
|
||||
inputType: {
|
||||
description: `The input type defines how the input data will be presented to your operation. Check the project wiki for a full description of each type. The options are: ${ioTypes.join(
|
||||
", ",
|
||||
)}.`,
|
||||
description: `The input type defines how the input data will be presented to your operation. Check the project wiki for a full description of each type. The options are: ${ioTypes.join(", ")}.`,
|
||||
example: "string",
|
||||
prompt: "Input type",
|
||||
type: "string",
|
||||
pattern: new RegExp(`^(${ioTypes.join("|")})$`),
|
||||
required: true,
|
||||
message: `The input type should be one of: ${ioTypes.join(", ")}.`,
|
||||
message: `The input type should be one of: ${ioTypes.join(", ")}.`
|
||||
},
|
||||
outputType: {
|
||||
description: `The output type tells CyberChef what sort of data you are returning from your operation. Check the project wiki for a full description of each type. The options are: ${ioTypes.join(
|
||||
", ",
|
||||
)}.`,
|
||||
description: `The output type tells CyberChef what sort of data you are returning from your operation. Check the project wiki for a full description of each type. The options are: ${ioTypes.join(", ")}.`,
|
||||
example: "string",
|
||||
prompt: "Output type",
|
||||
type: "string",
|
||||
pattern: new RegExp(`^(${ioTypes.join("|")})$`),
|
||||
required: true,
|
||||
message: `The output type should be one of: ${ioTypes.join(", ")}.`,
|
||||
message: `The output type should be one of: ${ioTypes.join(", ")}.`
|
||||
},
|
||||
highlight: {
|
||||
description:
|
||||
"If your operation does not change the length of the input in any way, we can enable highlighting. If it does change the length in a predictable way, we may still be able to enable highlighting and calculate the correct offsets. If this is not possible, we will disable highlighting for this operation.",
|
||||
description: "If your operation does not change the length of the input in any way, we can enable highlighting. If it does change the length in a predictable way, we may still be able to enable highlighting and calculate the correct offsets. If this is not possible, we will disable highlighting for this operation.",
|
||||
example: "true/false",
|
||||
prompt: "Enable highlighting",
|
||||
type: "boolean",
|
||||
default: "false",
|
||||
message:
|
||||
"Enter true or false to specify if highlighting should be enabled.",
|
||||
message: "Enter true or false to specify if highlighting should be enabled."
|
||||
},
|
||||
authorName: {
|
||||
description:
|
||||
"Your name or username will be added to the @author tag for this operation.",
|
||||
description: "Your name or username will be added to the @author tag for this operation.",
|
||||
example: "n1474335",
|
||||
prompt: "Username",
|
||||
type: "string",
|
||||
type: "string"
|
||||
},
|
||||
authorEmail: {
|
||||
description:
|
||||
"Your email address will also be added to the @author tag for this operation.",
|
||||
description: "Your email address will also be added to the @author tag for this operation.",
|
||||
example: "n1474335@gmail.com",
|
||||
prompt: "Email",
|
||||
type: "string",
|
||||
},
|
||||
},
|
||||
type: "string"
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Build schema
|
||||
for (const prop in schema.properties) {
|
||||
const p = schema.properties[prop];
|
||||
p.description =
|
||||
"\n" +
|
||||
colors.white(p.description) +
|
||||
colors.cyan("\nExample: " + p.example) +
|
||||
"\n" +
|
||||
colors.green(p.prompt);
|
||||
p.description = "\n" + colors.white(p.description) + colors.cyan("\nExample: " + p.example) + "\n" + colors.green(p.prompt);
|
||||
}
|
||||
|
||||
console.log(
|
||||
"\n\nThis script will generate a new operation template based on the information you provide. These values can be changed manually later."
|
||||
.yellow,
|
||||
);
|
||||
console.log("\n\nThis script will generate a new operation template based on the information you provide. These values can be changed manually later.".yellow);
|
||||
|
||||
prompt.message = "";
|
||||
prompt.delimiter = ":".green;
|
||||
|
@ -151,15 +119,14 @@ prompt.get(schema, (err, result) => {
|
|||
process.exit(0);
|
||||
}
|
||||
|
||||
const moduleName = result.opName
|
||||
.replace(/\w\S*/g, (txt) => {
|
||||
return txt.charAt(0).toUpperCase() + txt.substr(1);
|
||||
})
|
||||
.replace(/[\s-()./]/g, "");
|
||||
const moduleName = result.opName.replace(/\w\S*/g, txt => {
|
||||
return txt.charAt(0).toUpperCase() + txt.substr(1);
|
||||
}).replace(/[\s-()./]/g, "");
|
||||
|
||||
|
||||
const template = `/**
|
||||
* @author ${result.authorName} [${result.authorEmail}]
|
||||
* @copyright Crown Copyright ${new Date().getFullYear()}
|
||||
* @copyright Crown Copyright ${(new Date()).getFullYear()}
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
|
@ -179,10 +146,7 @@ class ${moduleName} extends Operation {
|
|||
|
||||
this.name = "${result.opName}";
|
||||
this.module = "${result.module}";
|
||||
this.description = "${new EscapeString().run(result.description, [
|
||||
"Special chars",
|
||||
"Double",
|
||||
])}";
|
||||
this.description = "${(new EscapeString).run(result.description, ["Special chars", "Double"])}";
|
||||
this.infoURL = "${result.infoURL}";
|
||||
this.inputType = "${result.inputType}";
|
||||
this.outputType = "${result.outputType}";
|
||||
|
@ -212,9 +176,7 @@ class ${moduleName} extends Operation {
|
|||
|
||||
throw new OperationError("Test");
|
||||
}
|
||||
${
|
||||
result.highlight
|
||||
? `
|
||||
${result.highlight ? `
|
||||
/**
|
||||
* Highlight ${result.opName}
|
||||
*
|
||||
|
@ -240,9 +202,7 @@ ${
|
|||
highlightReverse(pos, args) {
|
||||
return pos;
|
||||
}
|
||||
`
|
||||
: ""
|
||||
}
|
||||
` : ""}
|
||||
}
|
||||
|
||||
export default ${moduleName};
|
||||
|
@ -252,9 +212,7 @@ export default ${moduleName};
|
|||
|
||||
const filename = path.join(dir, `./${moduleName}.mjs`);
|
||||
if (fs.existsSync(filename)) {
|
||||
console.log(
|
||||
`${filename} already exists. It has NOT been overwritten.`.red,
|
||||
);
|
||||
console.log(`${filename} already exists. It has NOT been overwritten.`.red);
|
||||
console.log("Choose a different operation name to avoid conflicts.");
|
||||
process.exit(0);
|
||||
}
|
||||
|
@ -267,4 +225,6 @@ export default ${moduleName};
|
|||
3. Write tests in ${colors.green("tests/operations/tests/")}
|
||||
4. Run ${colors.cyan("npm run lint")} and ${colors.cyan("npm run test")}
|
||||
5. Submit a Pull Request to get your operation added to the official CyberChef repository.`);
|
||||
|
||||
});
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue