mirror of
https://github.com/gchq/CyberChef
synced 2025-12-05 23:53:27 +00:00
Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
38838e4dca | ||
|
|
5c151d727b | ||
|
|
2d5b157c91 | ||
|
|
10d3d27a33 | ||
|
|
1614442bd7 | ||
|
|
a3c5b1e107 | ||
|
|
f4de4de8c1 | ||
|
|
5155d0ed56 | ||
|
|
9be674103f | ||
|
|
8f7bb3a7c9 | ||
|
|
f957925aac | ||
|
|
1bf8d63d1a | ||
|
|
8875144307 | ||
|
|
d5c01f387a | ||
|
|
32709cd60f | ||
|
|
aaf0a91975 | ||
|
|
6cc6230b91 | ||
|
|
dd630f20f8 | ||
|
|
0c6efd95fa | ||
|
|
98d861a639 | ||
|
|
e638fb69b5 | ||
|
|
718a94b5e0 | ||
|
|
3079059ce3 | ||
|
|
d6c6981bc0 | ||
|
|
8aeb7b60a7 | ||
|
|
9197ac6510 | ||
|
|
b67ad3073c | ||
|
|
4a4f37f888 | ||
|
|
c55331f220 | ||
|
|
757ec98554 | ||
|
|
14309f2069 | ||
|
|
e6b89d571e | ||
|
|
d957198fd6 | ||
|
|
903bd22999 | ||
|
|
ab4c9ef0d6 | ||
|
|
a69063de9b | ||
|
|
62b76777c0 | ||
|
|
32a91bda0a | ||
|
|
a15af602e0 | ||
|
|
ec9dfd2918 | ||
|
|
016086ef4e | ||
|
|
2e5ea968ee | ||
|
|
5dde1c1c04 | ||
|
|
be14d56eae | ||
|
|
100b097ace | ||
|
|
3833c5f9fe | ||
|
|
3470dd9f3b | ||
|
|
c5e8649284 | ||
|
|
a95f43aa4d | ||
|
|
0420aa8edb | ||
|
|
806b43dfec | ||
|
|
fd96bf345b | ||
|
|
3abe99078e | ||
|
|
edbd540c68 | ||
|
|
06d9302d96 | ||
|
|
032b4bed7f | ||
|
|
8559f5c8ea |
4
.babelrc
4
.babelrc
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"presets": [
|
||||
["env", {
|
||||
["@babel/preset-env", {
|
||||
"targets": {
|
||||
"chrome": 40,
|
||||
"firefox": 35,
|
||||
@@ -8,7 +8,7 @@
|
||||
"node": "6.5"
|
||||
},
|
||||
"modules": false,
|
||||
"useBuiltIns": true
|
||||
"useBuiltIns": "entry"
|
||||
}]
|
||||
],
|
||||
"plugins": [
|
||||
|
||||
@@ -36,7 +36,7 @@ deploy:
|
||||
skip_cleanup: true
|
||||
email: "n1474335@gmail.com"
|
||||
api_key:
|
||||
secure: "Z3FK6bm4RfQEIRXZ1lBNzQkVIoHpivThr9U+XBHmsBgIfdrK/XUnzs/slugo+NIz8nPiGmMx4gxyJonBCLHDGb1ysky2aEWTl26c0teaF4DeQEjWC1ZaGzv8MV1/GkUamnr1qouXjyUhyEAp33rd8ccN9Rq3QNYB/qLDcA9/FCme7JCW6sCd4zWO0LGEYMJEMc2FzAUkqhqsI05hegGhSDgKXRn5PmLARek4yHD+Hx7pstaTeQIy0WoGJjdzoB3iJIMmo/hWZGzZafktUOh223c5qzx4zMpDRNmMngBUw6R94nKd4KvplYRgB87Y3L/aiVU4CF+axwLmK8RPaC1wbJnlHf06zxHPdiFmsY/zKPpNel+nOnxzRrF5l2KMU4TU6gug3s9Jnzp9T5UMfhp0jW3YkxHGeuOPOeE1i0lTUWUGWrPHLQquAhLfkr2zxaU4ETk/y85hq9W4LAy0ENEDVXX2jP7FnI4Z1fdpmljpmVNJR+outPg6t+Coqgvil7v7XpMtDm8lKQanVYuxwmkb/ncOWFRWuM2j5zIEg3CHnFDcJ9bYrfKRg0b0tb/2BWD14pQnV76goVwzJQYVzdPc8TKIYJw2BZ1Nh9c0iruQVebe/6l1FX9fDCkz8VMmltni61/LxZrf8y0NT1YaU1raeNY2dH5UWvEa9p72FPMI6Eg="
|
||||
secure: "UnDQL3Kh+GK2toL0TK3FObO0ujVssU3Eg4BBuYdjwLB81GhiGE5/DTh7THdZPOpbLo6wQeOwfZDuMeKC1OU+0Uf4NsdYFu1aq6xMO20qBQ4qUfgsyiK4Qgywj9gk0p1+OFZdGAZ/j1CNRAaF71XQIY6iV84c+SO4WoizXYrNT0Jh4sr2DA4/97G2xmJtPi0qOzYrJ09R56ZUozmqeik5G0pMRIuJRbpjS/7bZXV+N7WV0ombZc9RkUaetbabEVOLQ+Xx5YAIVq+VuEeMe9VBSnxY/FfCLmy1wJsjGzpLCyBI9nbrG4nw8Wgc2m8NfK9rcpIvBTGner9r2j60NVDkZ8kLZPrqXhq6AZMwa+oz6K5UQCqRo2RRQzSGwXxg67HY5Tcq+oNmjd+DqpPg4LZ3eGlluyP5XfG+hpSr9Ya4d8q8SrUWLxkoLHI6ZKMtoKFbTCSSQPiluW5hsZxjz3yDkkjsJw64M/EM8UyJrgaXqDklQu+7rBGKLfsK6os7RDiqjBWpQ7gwpo8HvY0O8yqEAabPz+QGkanpjcCOZCXFbSkzWxYy37RMAPu88iINVZVlZE4l+WJenCpZY95ueyy0mG9cyMSzVRPyX6A+/n4H6VMFPFjpGDLTD588ACEjY1lmHfS/eXwXJcgqPPD2gW0XdRdUheU/ssqlfCfGWQMTDXs="
|
||||
on:
|
||||
tags: true
|
||||
branch: master
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
# Changelog
|
||||
All notable changes to CyberChef will be documented in this file.
|
||||
|
||||
### [8.8.0] - 2018-10-10
|
||||
- 'Parse TLV' operation added [@GCHQ77703] | [#351]
|
||||
|
||||
### [8.7.0] - 2018-08-31
|
||||
- 'JWT Sign', 'JWT Verify' and 'JWT Decode' operations added [@GCHQ77703] | [#348]
|
||||
|
||||
### [8.6.0] - 2018-08-29
|
||||
- 'To Geohash' and 'From Geohash' operations added [@GCHQ77703] | [#344]
|
||||
@@ -48,6 +53,8 @@ All notable changes to CyberChef will be documented in this file.
|
||||
- Initial open source commit [@n1474335] | [b1d73a72](https://github.com/gchq/CyberChef/commit/b1d73a725dc7ab9fb7eb789296efd2b7e4b08306)
|
||||
|
||||
|
||||
[8.8.0]: https://github.com/gchq/CyberChef/releases/tag/v8.8.0
|
||||
[8.7.0]: https://github.com/gchq/CyberChef/releases/tag/v8.7.0
|
||||
[8.6.0]: https://github.com/gchq/CyberChef/releases/tag/v8.6.0
|
||||
[8.5.0]: https://github.com/gchq/CyberChef/releases/tag/v8.5.0
|
||||
[8.4.0]: https://github.com/gchq/CyberChef/releases/tag/v8.4.0
|
||||
@@ -86,3 +93,5 @@ All notable changes to CyberChef will be documented in this file.
|
||||
[#338]: https://github.com/gchq/CyberChef/pull/338
|
||||
[#340]: https://github.com/gchq/CyberChef/pull/340
|
||||
[#344]: https://github.com/gchq/CyberChef/pull/344
|
||||
[#348]: https://github.com/gchq/CyberChef/pull/348
|
||||
[#351]: https://github.com/gchq/CyberChef/pull/351
|
||||
|
||||
12
Gruntfile.js
12
Gruntfile.js
@@ -280,7 +280,11 @@ module.exports = function (grunt) {
|
||||
chunks: false,
|
||||
modules: false,
|
||||
entrypoints: false,
|
||||
warningsFilter: [/source-map/, /dependency is an expression/],
|
||||
warningsFilter: [
|
||||
/source-map/,
|
||||
/dependency is an expression/,
|
||||
/export 'default'/
|
||||
],
|
||||
}
|
||||
},
|
||||
start: {
|
||||
@@ -382,13 +386,13 @@ module.exports = function (grunt) {
|
||||
"mkdir -p src/core/config/modules",
|
||||
"echo 'export default {};\n' > src/core/config/modules/OpModules.mjs",
|
||||
"echo '[]\n' > src/core/config/OperationConfig.json",
|
||||
"node --experimental-modules src/core/config/scripts/generateOpsIndex.mjs",
|
||||
"node --experimental-modules src/core/config/scripts/generateConfig.mjs",
|
||||
"node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateOpsIndex.mjs",
|
||||
"node --experimental-modules --no-warnings --no-deprecation src/core/config/scripts/generateConfig.mjs",
|
||||
"echo '--- Config scripts finished. ---\n'"
|
||||
].join(";")
|
||||
},
|
||||
tests: {
|
||||
command: "node --experimental-modules test/index.mjs"
|
||||
command: "node --experimental-modules --no-warnings --no-deprecation test/index.mjs"
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
3565
package-lock.json
generated
3565
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
53
package.json
53
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "cyberchef",
|
||||
"version": "8.6.2",
|
||||
"version": "8.8.7",
|
||||
"description": "The Cyber Swiss Army Knife for encryption, encoding, compression and data analysis.",
|
||||
"author": "n1474335 <n1474335@gmail.com>",
|
||||
"homepage": "https://gchq.github.io/CyberChef",
|
||||
@@ -30,45 +30,45 @@
|
||||
"main": "build/node/CyberChef.js",
|
||||
"bugs": "https://github.com/gchq/CyberChef/issues",
|
||||
"devDependencies": {
|
||||
"autoprefixer": "^9.1.0",
|
||||
"babel-core": "^6.26.3",
|
||||
"babel-loader": "^7.1.5",
|
||||
"babel-preset-env": "^1.7.0",
|
||||
"@babel/core": "^7.1.2",
|
||||
"@babel/preset-env": "^7.1.0",
|
||||
"autoprefixer": "^9.1.5",
|
||||
"babel-loader": "^8.0.4",
|
||||
"bootstrap": "^4.1.3",
|
||||
"colors": "^1.3.1",
|
||||
"colors": "^1.3.2",
|
||||
"css-loader": "^1.0.0",
|
||||
"eslint": "^5.3.0",
|
||||
"eslint": "^5.6.1",
|
||||
"exports-loader": "^0.7.0",
|
||||
"extract-text-webpack-plugin": "^4.0.0-alpha0",
|
||||
"file-loader": "^1.1.11",
|
||||
"file-loader": "^2.0.0",
|
||||
"grunt": "^1.0.3",
|
||||
"grunt-accessibility": "~6.0.0",
|
||||
"grunt-chmod": "~1.1.1",
|
||||
"grunt-concurrent": "^2.3.1",
|
||||
"grunt-contrib-clean": "~1.1.0",
|
||||
"grunt-contrib-clean": "~2.0.0",
|
||||
"grunt-contrib-copy": "~1.0.0",
|
||||
"grunt-contrib-watch": "^1.1.0",
|
||||
"grunt-eslint": "^21.0.0",
|
||||
"grunt-exec": "~3.0.0",
|
||||
"grunt-jsdoc": "^2.2.1",
|
||||
"grunt-webpack": "^3.1.2",
|
||||
"grunt-jsdoc": "^2.3.0",
|
||||
"grunt-webpack": "^3.1.3",
|
||||
"html-webpack-plugin": "^3.2.0",
|
||||
"imports-loader": "^0.8.0",
|
||||
"ink-docstrap": "^1.3.2",
|
||||
"js-to-mjs": "^0.2.0",
|
||||
"jsdoc-babel": "^0.4.0",
|
||||
"node-sass": "^4.9.2",
|
||||
"postcss-css-variables": "^0.9.0",
|
||||
"jsdoc-babel": "^0.5.0",
|
||||
"node-sass": "^4.9.3",
|
||||
"postcss-css-variables": "^0.11.0",
|
||||
"postcss-import": "^12.0.0",
|
||||
"postcss-loader": "^2.1.6",
|
||||
"postcss-loader": "^3.0.0",
|
||||
"prompt": "^1.0.0",
|
||||
"sass-loader": "^7.1.0",
|
||||
"sitemap": "^1.13.0",
|
||||
"style-loader": "^0.21.0",
|
||||
"url-loader": "^1.0.1",
|
||||
"sitemap": "^2.0.1",
|
||||
"style-loader": "^0.23.1",
|
||||
"url-loader": "^1.1.2",
|
||||
"web-resource-inliner": "^4.2.1",
|
||||
"webpack": "^4.16.4",
|
||||
"webpack-dev-server": "^3.1.5",
|
||||
"webpack": "^4.20.2",
|
||||
"webpack-dev-server": "^3.1.9",
|
||||
"webpack-node-externals": "^1.7.2",
|
||||
"worker-loader": "^2.0.0"
|
||||
},
|
||||
@@ -91,23 +91,24 @@
|
||||
"esmangle": "^1.0.1",
|
||||
"esprima": "^4.0.1",
|
||||
"exif-parser": "^0.1.12",
|
||||
"file-saver": "^1.3.8",
|
||||
"file-saver": "^2.0.0-rc.3",
|
||||
"highlight.js": "^9.12.0",
|
||||
"jquery": "^3.3.1",
|
||||
"js-crc": "^0.2.0",
|
||||
"js-sha3": "^0.7.0",
|
||||
"js-sha3": "^0.8.0",
|
||||
"jsbn": "^1.1.0",
|
||||
"jsesc": "^2.5.1",
|
||||
"jsonpath": "^1.0.0",
|
||||
"jsonwebtoken": "^8.3.0",
|
||||
"jsrsasign": "8.0.12",
|
||||
"kbpgp": "^2.0.77",
|
||||
"lodash": "^4.17.10",
|
||||
"kbpgp": "^2.0.80",
|
||||
"lodash": "^4.17.11",
|
||||
"loglevel": "^1.6.1",
|
||||
"loglevel-message-prefix": "^3.0.0",
|
||||
"moment": "^2.22.2",
|
||||
"moment-timezone": "^0.5.21",
|
||||
"ngeohash": "^0.6.0",
|
||||
"node-forge": "^0.7.5",
|
||||
"node-forge": "^0.7.6",
|
||||
"node-md6": "^0.1.0",
|
||||
"notepack.io": "^2.1.3",
|
||||
"nwmatcher": "^1.4.4",
|
||||
@@ -116,7 +117,7 @@
|
||||
"scryptsy": "^2.0.0",
|
||||
"snackbarjs": "^1.1.0",
|
||||
"sortablejs": "^1.7.0",
|
||||
"split.js": "^1.3.5",
|
||||
"split.js": "^1.5.2",
|
||||
"ssdeep.js": "0.0.2",
|
||||
"ua-parser-js": "^0.7.18",
|
||||
"utf8": "^3.0.0",
|
||||
|
||||
@@ -555,8 +555,6 @@ class Utils {
|
||||
if (renderNext) {
|
||||
cell += b;
|
||||
renderNext = false;
|
||||
} else if (b === "\\") {
|
||||
renderNext = true;
|
||||
} else if (b === "\"" && !inString) {
|
||||
inString = true;
|
||||
} else if (b === "\"" && inString) {
|
||||
|
||||
@@ -53,7 +53,8 @@
|
||||
"To MessagePack",
|
||||
"From MessagePack",
|
||||
"To Braille",
|
||||
"From Braille"
|
||||
"From Braille",
|
||||
"Parse TLV"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -89,6 +90,9 @@
|
||||
"Derive EVP key",
|
||||
"Bcrypt",
|
||||
"Scrypt",
|
||||
"JWT Sign",
|
||||
"JWT Verify",
|
||||
"JWT Decode",
|
||||
"Pseudo-Random Number Generator"
|
||||
]
|
||||
},
|
||||
|
||||
78
src/core/lib/TLVParser.mjs
Normal file
78
src/core/lib/TLVParser.mjs
Normal file
@@ -0,0 +1,78 @@
|
||||
/**
|
||||
* Parser for Type-length-value data.
|
||||
*
|
||||
* @author gchq77703 []
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
const defaults = {
|
||||
location: 0,
|
||||
bytesInLength: 1,
|
||||
basicEncodingRules: false
|
||||
};
|
||||
|
||||
/**
|
||||
* TLVParser library
|
||||
*/
|
||||
export default class TLVParser {
|
||||
|
||||
/**
|
||||
* TLVParser constructor
|
||||
*
|
||||
* @param {byteArray} input
|
||||
* @param {Object} options
|
||||
*/
|
||||
constructor(input, options) {
|
||||
this.input = input;
|
||||
Object.assign(this, defaults, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {number}
|
||||
*/
|
||||
getLength() {
|
||||
if (this.basicEncodingRules) {
|
||||
const bit = this.input[this.location];
|
||||
if (bit & 0x80) {
|
||||
this.bytesInLength = bit & ~0x80;
|
||||
} else {
|
||||
this.location++;
|
||||
return bit & ~0x80;
|
||||
}
|
||||
}
|
||||
|
||||
let length = 0;
|
||||
|
||||
for (let i = 0; i < this.bytesInLength; i++) {
|
||||
length += this.input[this.location] * Math.pow(Math.pow(2, 8), i);
|
||||
this.location++;
|
||||
}
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {number} length
|
||||
* @returns {number[]}
|
||||
*/
|
||||
getValue(length) {
|
||||
const value = [];
|
||||
|
||||
for (let i = 0; i < length; i++) {
|
||||
if (this.location > this.input.length) return value;
|
||||
value.push(this.input[this.location]);
|
||||
this.location++;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {boolean}
|
||||
*/
|
||||
atEnd() {
|
||||
return this.input.length <= this.location;
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import bzip2 from "../vendor/bzip2.js";
|
||||
import bzip2 from "../vendor/bzip2";
|
||||
import OperationError from "../errors/OperationError";
|
||||
|
||||
/**
|
||||
|
||||
@@ -39,8 +39,8 @@ class ExtractEmailAddresses extends Operation {
|
||||
*/
|
||||
run(input, args) {
|
||||
const displayTotal = args[0],
|
||||
regex = /\b\w[-.\w]*@[-\w]+(?:\.[-\w]+)*\.[A-Z]{2,4}\b/ig;
|
||||
|
||||
// email regex from: https://www.regextester.com/98066
|
||||
regex = /(?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9])?\.)+[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9](?:[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9-]*[\u00A0-\uD7FF\uE000-\uFFFF-a-z0-9])?|\[(?:(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9]))\.){3}(?:(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])/ig;
|
||||
return search(input, regex, null, displayTotal);
|
||||
}
|
||||
|
||||
|
||||
@@ -71,6 +71,11 @@ class FromBase58 extends Operation {
|
||||
|
||||
if (input.length === 0) return [];
|
||||
|
||||
let zeroPrefix = 0;
|
||||
for (let i = 0; i < input.length && input[i] === alphabet[0]; i++) {
|
||||
zeroPrefix++;
|
||||
}
|
||||
|
||||
[].forEach.call(input, function(c, charIndex) {
|
||||
const index = alphabet.indexOf(c);
|
||||
|
||||
@@ -98,6 +103,10 @@ class FromBase58 extends Operation {
|
||||
}
|
||||
});
|
||||
|
||||
while (zeroPrefix--) {
|
||||
result.push(0);
|
||||
}
|
||||
|
||||
return result.reverse();
|
||||
}
|
||||
|
||||
|
||||
51
src/core/operations/JWTDecode.mjs
Normal file
51
src/core/operations/JWTDecode.mjs
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* @author gchq77703 []
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import jwt from "jsonwebtoken";
|
||||
import OperationError from "../errors/OperationError";
|
||||
|
||||
/**
|
||||
* JWT Decode operation
|
||||
*/
|
||||
class JWTDecode extends Operation {
|
||||
|
||||
/**
|
||||
* JWTDecode constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "JWT Decode";
|
||||
this.module = "Crypto";
|
||||
this.description = "Decodes a JSON Web Token <b>without</b> checking whether the provided secret / private key is valid. Use 'JWT Verify' to check if the signature is valid as well.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/JSON_Web_Token";
|
||||
this.inputType = "string";
|
||||
this.outputType = "JSON";
|
||||
this.args = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {JSON}
|
||||
*/
|
||||
run(input, args) {
|
||||
try {
|
||||
const decoded = jwt.decode(input, {
|
||||
json: true,
|
||||
complete: true
|
||||
});
|
||||
|
||||
return decoded.payload;
|
||||
} catch (err) {
|
||||
throw new OperationError(err);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default JWTDecode;
|
||||
74
src/core/operations/JWTSign.mjs
Normal file
74
src/core/operations/JWTSign.mjs
Normal file
@@ -0,0 +1,74 @@
|
||||
/**
|
||||
* @author gchq77703 []
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import jwt from "jsonwebtoken";
|
||||
import OperationError from "../errors/OperationError";
|
||||
|
||||
/**
|
||||
* JWT Sign operation
|
||||
*/
|
||||
class JWTSign extends Operation {
|
||||
|
||||
/**
|
||||
* JWTSign constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "JWT Sign";
|
||||
this.module = "Crypto";
|
||||
this.description = "Signs a JSON object as a JSON Web Token using a provided secret / private key.<br><br>The key should be either the secret for HMAC algorithms or the PEM-encoded private key for RSA and ECDSA.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/JSON_Web_Token";
|
||||
this.inputType = "JSON";
|
||||
this.outputType = "string";
|
||||
this.args = [
|
||||
{
|
||||
name: "Private/Secret Key",
|
||||
type: "text",
|
||||
value: "secret"
|
||||
},
|
||||
{
|
||||
name: "Signing algorithm",
|
||||
type: "option",
|
||||
value: [
|
||||
"HS256",
|
||||
"HS384",
|
||||
"HS512",
|
||||
"RS256",
|
||||
"RS384",
|
||||
"RS512",
|
||||
"ES256",
|
||||
"ES384",
|
||||
"ES512",
|
||||
"None"
|
||||
]
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {JSON} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [key, algorithm] = args;
|
||||
|
||||
try {
|
||||
return jwt.sign(input, key, {
|
||||
algorithm: algorithm === "None" ? "none" : algorithm
|
||||
});
|
||||
} catch (err) {
|
||||
throw new OperationError(`Error: Have you entered the key correctly? The key should be either the secret for HMAC algorithms or the PEM-encoded private key for RSA and ECDSA.
|
||||
|
||||
${err}`);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default JWTSign;
|
||||
65
src/core/operations/JWTVerify.mjs
Normal file
65
src/core/operations/JWTVerify.mjs
Normal file
@@ -0,0 +1,65 @@
|
||||
/**
|
||||
* @author gchq77703 []
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import jwt from "jsonwebtoken";
|
||||
import OperationError from "../errors/OperationError";
|
||||
|
||||
/**
|
||||
* JWT Verify operation
|
||||
*/
|
||||
class JWTVerify extends Operation {
|
||||
|
||||
/**
|
||||
* JWTVerify constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "JWT Verify";
|
||||
this.module = "Crypto";
|
||||
this.description = "Verifies that a JSON Web Token is valid and has been signed with the provided secret / private key.<br><br>The key should be either the secret for HMAC algorithms or the PEM-encoded private key for RSA and ECDSA.";
|
||||
this.infoURL = "https://wikipedia.org/wiki/JSON_Web_Token";
|
||||
this.inputType = "string";
|
||||
this.outputType = "JSON";
|
||||
this.args = [
|
||||
{
|
||||
name: "Private/Secret Key",
|
||||
type: "text",
|
||||
value: "secret"
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {string} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [key] = args;
|
||||
|
||||
try {
|
||||
const verified = jwt.verify(input, key, { algorithms: [
|
||||
"HS256",
|
||||
"HS384",
|
||||
"HS512",
|
||||
"none"
|
||||
]});
|
||||
|
||||
if (verified.hasOwnProperty("name") && verified.name === "JsonWebTokenError") {
|
||||
throw new OperationError(verified.message);
|
||||
}
|
||||
|
||||
return verified;
|
||||
} catch (err) {
|
||||
throw new OperationError(err);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default JWTVerify;
|
||||
76
src/core/operations/ParseTLV.mjs
Normal file
76
src/core/operations/ParseTLV.mjs
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* @author gchq77703 []
|
||||
* @author n1474335 [n1474335@gmail.com]
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import Operation from "../Operation";
|
||||
import TLVParser from "../lib/TLVParser";
|
||||
import OperationError from "../errors/OperationError";
|
||||
|
||||
/**
|
||||
* Parse TLV operation
|
||||
*/
|
||||
class ParseTLV extends Operation {
|
||||
|
||||
/**
|
||||
* ParseTLV constructor
|
||||
*/
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.name = "Parse TLV";
|
||||
this.module = "Default";
|
||||
this.description = "Converts a Type-Length-Value (TLV) encoded string into a JSON object. Can optionally include a <code>Key</code> / <code>Type</code> entry. <br><br>Tags: Key-Length-Value, KLV, Length-Value, LV";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Type-length-value";
|
||||
this.inputType = "byteArray";
|
||||
this.outputType = "JSON";
|
||||
this.args = [
|
||||
{
|
||||
name: "Type/Key size",
|
||||
type: "number",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: "Length size",
|
||||
type: "number",
|
||||
value: 1
|
||||
},
|
||||
{
|
||||
name: "Use BER",
|
||||
type: "boolean",
|
||||
value: false
|
||||
}
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {byteArray} input
|
||||
* @param {Object[]} args
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const [bytesInKey, bytesInLength, basicEncodingRules] = args;
|
||||
|
||||
if (bytesInKey <= 0 && bytesInLength <= 0)
|
||||
throw new OperationError("Type or Length size must be greater than 0");
|
||||
|
||||
const tlv = new TLVParser(input, { bytesInLength, basicEncodingRules });
|
||||
|
||||
const data = [];
|
||||
|
||||
while (!tlv.atEnd()) {
|
||||
const key = bytesInKey ? tlv.getValue(bytesInKey) : undefined;
|
||||
const length = tlv.getLength();
|
||||
const value = tlv.getValue(length);
|
||||
|
||||
data.push({ key, length, value });
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export default ParseTLV;
|
||||
@@ -227,6 +227,7 @@ function regexList (input, regex, displayTotal, matches, captureGroups) {
|
||||
*/
|
||||
function regexHighlight (input, regex, displayTotal) {
|
||||
let output = "",
|
||||
title = "",
|
||||
m,
|
||||
hl = 1,
|
||||
i = 0,
|
||||
@@ -241,8 +242,16 @@ function regexHighlight (input, regex, displayTotal) {
|
||||
// Add up to match
|
||||
output += Utils.escapeHtml(input.slice(i, m.index));
|
||||
|
||||
title = `Offset: ${m.index}\n`;
|
||||
if (m.length > 1) {
|
||||
title += "Groups:\n";
|
||||
for (let n = 1; n < m.length; ++n) {
|
||||
title += `\t${n}: ${m[n]}\n`;
|
||||
}
|
||||
}
|
||||
|
||||
// Add match with highlighting
|
||||
output += "<span class='hl"+hl+"'>" + Utils.escapeHtml(m[0]) + "</span>";
|
||||
output += "<span class='hl"+hl+"' title='"+title+"'>" + Utils.escapeHtml(m[0]) + "</span>";
|
||||
|
||||
// Switch highlight
|
||||
hl = hl === 1 ? 2 : 1;
|
||||
|
||||
@@ -62,7 +62,7 @@ class Scrypt extends Operation {
|
||||
* @returns {string}
|
||||
*/
|
||||
run(input, args) {
|
||||
const salt = Utils.convertToByteString(args[0].string || "", args[0].option),
|
||||
const salt = Buffer.from(Utils.convertToByteArray(args[0].string || "", args[0].option)),
|
||||
iterations = args[1],
|
||||
memFactor = args[2],
|
||||
parallelFactor = args[3],
|
||||
|
||||
@@ -53,6 +53,11 @@ class ToBase58 extends Operation {
|
||||
|
||||
if (input.length === 0) return "";
|
||||
|
||||
let zeroPrefix = 0;
|
||||
for (let i = 0; i < input.length && input[i] === 0; i++) {
|
||||
zeroPrefix++;
|
||||
}
|
||||
|
||||
input.forEach(function(b) {
|
||||
let carry = (result[0] << 8) + b;
|
||||
result[0] = carry % 58;
|
||||
@@ -74,7 +79,7 @@ class ToBase58 extends Operation {
|
||||
return alphabet[b];
|
||||
}).reverse().join("");
|
||||
|
||||
while (result.length < input.length) {
|
||||
while (zeroPrefix--) {
|
||||
result = alphabet[0] + result;
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ class Whirlpool extends Operation {
|
||||
|
||||
this.name = "Whirlpool";
|
||||
this.module = "Hashing";
|
||||
this.description = "Whirlpool is a cryptographic hash function designed by Vincent Rijmen (co-creator of AES) and Paulo S. L. M. Barreto, who first described it in 2000.<br><br>Several variants exist:<ul><li>Whirlpool-0 is the original version released in 2000.</li><li>Whirlpool-T is the first revision, released in 2001, improving the generation of the s-box.</li><li>Wirlpool is the latest revision, released in 2003, fixing a flaw in the difusion matrix.</li></ul>";
|
||||
this.description = "Whirlpool is a cryptographic hash function designed by Vincent Rijmen (co-creator of AES) and Paulo S. L. M. Barreto, who first described it in 2000.<br><br>Several variants exist:<ul><li>Whirlpool-0 is the original version released in 2000.</li><li>Whirlpool-T is the first revision, released in 2001, improving the generation of the s-box.</li><li>Whirlpool is the latest revision, released in 2003, fixing a flaw in the difusion matrix.</li></ul>";
|
||||
this.infoURL = "https://wikipedia.org/wiki/Whirlpool_(cryptography)";
|
||||
this.inputType = "ArrayBuffer";
|
||||
this.outputType = "string";
|
||||
|
||||
@@ -262,4 +262,4 @@ bzip2.decompress = function(bits, size, len){
|
||||
return output;
|
||||
}
|
||||
|
||||
module.exports = bzip2;
|
||||
export default bzip2;
|
||||
@@ -67,6 +67,7 @@ class BackgroundWorkerWaiter {
|
||||
log.debug("Background ChefWorker loaded");
|
||||
break;
|
||||
case "optionUpdate":
|
||||
case "statusMessage":
|
||||
// Ignore these messages
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -154,7 +154,7 @@ class HTMLIngredient {
|
||||
} else if ((m = this.value[i].name.match(/\[\/([a-z0-9 -()^]+)\]/i))) {
|
||||
html += "</optgroup>";
|
||||
} else {
|
||||
html += `<option populate-value="${this.value[i].value}">${this.value[i].name}</option>`;
|
||||
html += `<option populate-value='${this.value[i].value}'>${this.value[i].name}</option>`;
|
||||
}
|
||||
}
|
||||
html += `</select>
|
||||
|
||||
@@ -131,14 +131,16 @@ class HTMLOperation {
|
||||
*/
|
||||
function titleFromWikiLink(url) {
|
||||
const splitURL = url.split("/");
|
||||
if (splitURL.indexOf("wiki") < 0) {
|
||||
if (splitURL.indexOf("wikipedia.org") < 0 && splitURL.indexOf("forensicswiki.org") < 0) {
|
||||
// Not a wiki link, return full URL
|
||||
return `<a href='${url}' target='_blank'>More Information<i class='material-icons inline-icon'>open_in_new</i></a>`;
|
||||
}
|
||||
|
||||
const wikiName = splitURL.indexOf("forensicswiki.org") < 0 ? "Wikipedia" : "Forensics Wiki";
|
||||
|
||||
const pageTitle = decodeURIComponent(splitURL[splitURL.length - 1])
|
||||
.replace(/_/g, " ");
|
||||
return `<a href='${url}' target='_blank'>${pageTitle}<i class='material-icons inline-icon'>open_in_new</i></a> on Wikipedia`;
|
||||
return `<a href='${url}' target='_blank'>${pageTitle}<i class='material-icons inline-icon'>open_in_new</i></a> on ${wikiName}`;
|
||||
}
|
||||
|
||||
export default HTMLOperation;
|
||||
|
||||
@@ -116,6 +116,13 @@ div.toggle-string {
|
||||
left: 12px;
|
||||
}
|
||||
|
||||
.operation label.bmd-label-floating {
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
width: calc(100% - 13px);
|
||||
}
|
||||
|
||||
.operation .bmd-form-group .bmd-help {
|
||||
margin-top: -17px;
|
||||
}
|
||||
@@ -172,6 +179,7 @@ div.toggle-string {
|
||||
background-color: var(--fc-operation-border-colour);
|
||||
font-family: var(--fixed-width-font-family);
|
||||
padding: 10px;
|
||||
word-break: break-all;
|
||||
}
|
||||
|
||||
.op-icon {
|
||||
|
||||
@@ -24,49 +24,55 @@ global.ENVIRONMENT_IS_WEB = function() {
|
||||
};
|
||||
|
||||
import TestRegister from "./TestRegister";
|
||||
import "./tests/operations/BCD";
|
||||
import "./tests/operations/BSON";
|
||||
import "./tests/operations/Base58";
|
||||
import "./tests/operations/Base64";
|
||||
import "./tests/operations/BCD";
|
||||
import "./tests/operations/BitwiseOp";
|
||||
import "./tests/operations/BSON";
|
||||
import "./tests/operations/ByteRepr";
|
||||
import "./tests/operations/CartesianProduct";
|
||||
import "./tests/operations/CharEnc";
|
||||
import "./tests/operations/Ciphers";
|
||||
import "./tests/operations/Checksum";
|
||||
import "./tests/operations/Ciphers";
|
||||
import "./tests/operations/Code";
|
||||
import "./tests/operations/Comment";
|
||||
import "./tests/operations/Compress";
|
||||
import "./tests/operations/ConditionalJump";
|
||||
import "./tests/operations/Crypt";
|
||||
import "./tests/operations/DateTime";
|
||||
import "./tests/operations/ExtractEmailAddresses";
|
||||
import "./tests/operations/Fork";
|
||||
import "./tests/operations/Jump";
|
||||
import "./tests/operations/ConditionalJump";
|
||||
import "./tests/operations/Register";
|
||||
import "./tests/operations/Comment";
|
||||
import "./tests/operations/FromGeohash.mjs";
|
||||
import "./tests/operations/Hash";
|
||||
import "./tests/operations/HaversineDistance";
|
||||
import "./tests/operations/Hexdump";
|
||||
import "./tests/operations/Image";
|
||||
import "./tests/operations/MorseCode";
|
||||
import "./tests/operations/Jump";
|
||||
import "./tests/operations/JWTDecode";
|
||||
import "./tests/operations/JWTSign";
|
||||
import "./tests/operations/JWTVerify";
|
||||
import "./tests/operations/MS";
|
||||
import "./tests/operations/PGP";
|
||||
import "./tests/operations/PHP";
|
||||
import "./tests/operations/Magic";
|
||||
import "./tests/operations/MorseCode";
|
||||
import "./tests/operations/NetBIOS";
|
||||
import "./tests/operations/OTP";
|
||||
import "./tests/operations/PGP";
|
||||
import "./tests/operations/PHP";
|
||||
import "./tests/operations/ParseIPRange";
|
||||
import "./tests/operations/PowerSet";
|
||||
import "./tests/operations/Regex";
|
||||
import "./tests/operations/Register";
|
||||
import "./tests/operations/Rotate";
|
||||
import "./tests/operations/StrUtils";
|
||||
import "./tests/operations/SeqUtils";
|
||||
import "./tests/operations/SetDifference";
|
||||
import "./tests/operations/SetIntersection";
|
||||
import "./tests/operations/SetUnion";
|
||||
import "./tests/operations/StrUtils";
|
||||
import "./tests/operations/SymmetricDifference";
|
||||
import "./tests/operations/ToGeohash.mjs";
|
||||
import "./tests/operations/TranslateDateTimeFormat";
|
||||
import "./tests/operations/Magic";
|
||||
import "./tests/operations/ToGeohash.mjs";
|
||||
import "./tests/operations/FromGeohash.mjs";
|
||||
import "./tests/operations/ParseIPRange";
|
||||
import "./tests/operations/ParseTLV";
|
||||
|
||||
let allTestsPassing = true;
|
||||
const testStatusCounts = {
|
||||
|
||||
@@ -53,6 +53,28 @@ TestRegister.addTests([
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "To Base58 with null prefix and suffix",
|
||||
input: "\0\0\0Hello\0\0\0",
|
||||
expectedOutput: "111D7LMXYjHjTu",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "To Base58",
|
||||
args: ["123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "From Base58 with null prefix and suffix",
|
||||
input: "111D7LMXYjHjTu",
|
||||
expectedOutput: "\0\0\0Hello\0\0\0",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "From Base58",
|
||||
args: ["123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "From Base58 (Bitcoin): 'StV1DL6CwTryKyV'",
|
||||
input: "StV1DL6CwTryKyV",
|
||||
|
||||
55
test/tests/operations/ExtractEmailAddresses.mjs
Normal file
55
test/tests/operations/ExtractEmailAddresses.mjs
Normal file
@@ -0,0 +1,55 @@
|
||||
/**
|
||||
* extract email address tests.
|
||||
*
|
||||
* @author Klaxon [klaxon@veyr.com]
|
||||
* @copyright Crown Copyright 2017
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../TestRegister";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Extract email address",
|
||||
input: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com email@example.name\nemail@example.museum email@example.co.jp firstname-lastname@example.com",
|
||||
expectedOutput: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com\n",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract email addresses",
|
||||
"args": [false]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Extract email address - Display total",
|
||||
input: "email@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com email@example.name\nemail@example.museum email@example.co.jp firstname-lastname@example.com",
|
||||
expectedOutput: "Total found: 11\n\nemail@example.com\nfirstname.lastname@example.com\nemail@subdomain.example.com\nfirstname+lastname@example.com\n1234567890@example.com\nemail@example-one.com\n_______@example.com\nemail@example.name\nemail@example.museum\nemail@example.co.jp\nfirstname-lastname@example.com\n",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract email addresses",
|
||||
"args": [true]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Extract email address (Internationalized)",
|
||||
input: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9 \u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c \u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc Jos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com and Jos\u1ec5Silva@google.com\nFoO@BaR.CoM, john@192.168.10.100\ng\xf3mez@junk.br and Abc.123@example.com.\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com",
|
||||
expectedOutput: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com\n",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract email addresses",
|
||||
"args": [false]
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "Extract email address - Display total (Internationalized)",
|
||||
input: "\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9 \u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c \u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc Jos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com and Jos\u1ec5Silva@google.com\nFoO@BaR.CoM, john@192.168.10.100\ng\xf3mez@junk.br and Abc.123@example.com.\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com",
|
||||
expectedOutput: "Total found: 19\n\n\u4f0a\u662d\u5091@\u90f5\u4ef6.\u5546\u52d9\n\u093e\u092e@\u092e\u094b\u0939\u0928.\u0908\u0928\u094d\u092b\u094b\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nJos\u1ec5Silv\u1ec5@googl\u1ec5.com\nJos\u1ec5Silv\u1ec5@google.com\nJos\u1ec5Silva@google.com\nFoO@BaR.CoM\njohn@192.168.10.100\ng\xf3mez@junk.br\nAbc.123@example.com\nuser+mailbox/department=shipping@example.com\n\u7528\u6237@\u4f8b\u5b50.\u5e7f\u544a\n\u0909\u092a\u092f\u094b\u0917\u0915\u0930\u094d\u0924\u093e@\u0909\u0926\u093e\u0939\u0930\u0923.\u0915\u0949\u092e\n\u044e\u0437\u0435\u0440@\u0435\u043a\u0437\u0430\u043c\u043f\u043b.\u043a\u043e\u043c\n\u03b8\u03c3\u03b5\u03c1@\u03b5\u03c7\u03b1\u03bc\u03c0\u03bb\u03b5.\u03c8\u03bf\u03bc\nD\xf6rte@S\xf6rensen.example.com\n\u0430\u0434\u0436\u0430\u0439@\u044d\u043a\u0437\u0430\u043c\u043f\u043b.\u0440\u0443\u0441\ntest@xn--bcher-kva.com\n",
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Extract email addresses",
|
||||
"args": [true]
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
51
test/tests/operations/JWTDecode.mjs
Normal file
51
test/tests/operations/JWTDecode.mjs
Normal file
@@ -0,0 +1,51 @@
|
||||
/**
|
||||
* JWT Decode tests
|
||||
*
|
||||
* @author gchq77703 []
|
||||
*
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../TestRegister";
|
||||
|
||||
const outputObject = JSON.stringify({
|
||||
String: "SomeString",
|
||||
Number: 42,
|
||||
iat: 1
|
||||
}, null, 4);
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "JWT Decode: HS",
|
||||
input: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.0ha6-j4FwvEIKPVZ-hf3S_R9Hy_UtXzq4dnedXcUrXk",
|
||||
expectedOutput: outputObject,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Decode",
|
||||
args: [],
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "JWT Decode: RS",
|
||||
input: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.MjEJhtZk2nXzigi24piMzANmrj3mILHJcDl0xOjl5a8EgdKVL1oaMEjTkMQp5RA8YrqeRBFaX-BGGCKOXn5zPY1DJwWsBUyN9C-wGR2Qye0eogH_3b4M9EW00TPCUPXm2rx8URFj7Wg9VlsmrGzLV2oKkPgkVxuFSxnpO3yjn1Y",
|
||||
expectedOutput: outputObject,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Decode",
|
||||
args: [],
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "JWT Decode: ES",
|
||||
input: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.WkECT51jSfpRkcpQ4x0h5Dwe7CFBI6u6Et2gWp91HC7mpN_qCFadRpsvJLtKubm6cJTLa68xtei0YrDD8fxIUA",
|
||||
expectedOutput: outputObject,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Decode",
|
||||
args: [],
|
||||
}
|
||||
],
|
||||
}
|
||||
]);
|
||||
163
test/tests/operations/JWTSign.mjs
Normal file
163
test/tests/operations/JWTSign.mjs
Normal file
@@ -0,0 +1,163 @@
|
||||
/**
|
||||
* JWT Sign tests
|
||||
*
|
||||
* @author gchq77703 []
|
||||
*
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../TestRegister";
|
||||
|
||||
const inputObject = JSON.stringify({
|
||||
String: "SomeString",
|
||||
Number: 42,
|
||||
iat: 1
|
||||
}, null, 4);
|
||||
|
||||
const hsKey = "secret_cat";
|
||||
const rsKey = `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICWwIBAAKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw
|
||||
33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW
|
||||
+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQAB
|
||||
AoGAD+onAtVye4ic7VR7V50DF9bOnwRwNXrARcDhq9LWNRrRGElESYYTQ6EbatXS
|
||||
3MCyjjX2eMhu/aF5YhXBwkppwxg+EOmXeh+MzL7Zh284OuPbkglAaGhV9bb6/5Cp
|
||||
uGb1esyPbYW+Ty2PC0GSZfIXkXs76jXAu9TOBvD0ybc2YlkCQQDywg2R/7t3Q2OE
|
||||
2+yo382CLJdrlSLVROWKwb4tb2PjhY4XAwV8d1vy0RenxTB+K5Mu57uVSTHtrMK0
|
||||
GAtFr833AkEA6avx20OHo61Yela/4k5kQDtjEf1N0LfI+BcWZtxsS3jDM3i1Hp0K
|
||||
Su5rsCPb8acJo5RO26gGVrfAsDcIXKC+bQJAZZ2XIpsitLyPpuiMOvBbzPavd4gY
|
||||
6Z8KWrfYzJoI/Q9FuBo6rKwl4BFoToD7WIUS+hpkagwWiz+6zLoX1dbOZwJACmH5
|
||||
fSSjAkLRi54PKJ8TFUeOP15h9sQzydI8zJU+upvDEKZsZc/UhT/SySDOxQ4G/523
|
||||
Y0sz/OZtSWcol/UMgQJALesy++GdvoIDLfJX5GBQpuFgFenRiRDabxrE9MNUZ2aP
|
||||
FaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw==
|
||||
-----END RSA PRIVATE KEY-----`;
|
||||
const esKey = `-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgevZzL1gdAFr88hb2
|
||||
OF/2NxApJCzGCEDdfSp6VQO30hyhRANCAAQRWz+jn65BtOMvdyHKcvjBeBSDZH2r
|
||||
1RTwjmYSi9R/zpBnuQ4EiMnCqfMPWiZqB4QdbAd0E7oH50VpuZ1P087G
|
||||
-----END PRIVATE KEY-----`;
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "JWT Sign: HS256",
|
||||
input: inputObject,
|
||||
expectedOutput: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.0ha6-j4FwvEIKPVZ-hf3S_R9Hy_UtXzq4dnedXcUrXk",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Sign",
|
||||
args: [hsKey, "HS256"],
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "JWT Sign: HS384",
|
||||
input: inputObject,
|
||||
expectedOutput: "eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ._bPK-Y3mIACConbJqkGFMQ_L3vbxgKXy9gSxtL9hA5XTganozTSXxD0vX0N1yT5s",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Sign",
|
||||
args: [hsKey, "HS384"],
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "JWT Sign: HS512",
|
||||
input: inputObject,
|
||||
expectedOutput: "eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.vZIJU4XYMFt3FLE1V_RZOxEetmV4RvxtPZQGzJthK_d47pjwlEb6pQE23YxHFmOj8H5RLEdqqLPw4jNsOyHRzA",
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Sign",
|
||||
args: [hsKey, "HS512"],
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "JWT Sign: ES256",
|
||||
input: inputObject,
|
||||
expectedOutput: inputObject,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Sign",
|
||||
args: [esKey, "ES256"],
|
||||
},
|
||||
{
|
||||
op: "JWT Decode",
|
||||
args: []
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "JWT Sign: ES384",
|
||||
input: inputObject,
|
||||
expectedOutput: inputObject,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Sign",
|
||||
args: [esKey, "ES384"],
|
||||
},
|
||||
{
|
||||
op: "JWT Decode",
|
||||
args: []
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "JWT Sign: ES512",
|
||||
input: inputObject,
|
||||
expectedOutput: inputObject,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Sign",
|
||||
args: [esKey, "ES512"],
|
||||
},
|
||||
{
|
||||
op: "JWT Decode",
|
||||
args: []
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "JWT Sign: RS256",
|
||||
input: inputObject,
|
||||
expectedOutput: inputObject,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Sign",
|
||||
args: [rsKey, "RS256"],
|
||||
},
|
||||
{
|
||||
op: "JWT Decode",
|
||||
args: []
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "JWT Sign: RS384",
|
||||
input: inputObject,
|
||||
expectedOutput: inputObject,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Sign",
|
||||
args: [rsKey, "RS384"],
|
||||
},
|
||||
{
|
||||
op: "JWT Decode",
|
||||
args: []
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "JWT Sign: RS512",
|
||||
input: inputObject,
|
||||
expectedOutput: inputObject,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Sign",
|
||||
args: [esKey, "RS512"],
|
||||
},
|
||||
{
|
||||
op: "JWT Decode",
|
||||
args: []
|
||||
}
|
||||
],
|
||||
}
|
||||
]);
|
||||
75
test/tests/operations/JWTVerify.mjs
Normal file
75
test/tests/operations/JWTVerify.mjs
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* JWT Verify tests
|
||||
*
|
||||
* @author gchq77703 []
|
||||
*
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
import TestRegister from "../../TestRegister";
|
||||
|
||||
const outputObject = JSON.stringify({
|
||||
String: "SomeString",
|
||||
Number: 42,
|
||||
iat: 1
|
||||
}, null, 4);
|
||||
|
||||
const invalidAlgorithm = "JsonWebTokenError: invalid algorithm";
|
||||
|
||||
const hsKey = "secret_cat";
|
||||
const rsKey = `-----BEGIN RSA PRIVATE KEY-----
|
||||
MIICWwIBAAKBgQDdlatRjRjogo3WojgGHFHYLugdUWAY9iR3fy4arWNA1KoS8kVw
|
||||
33cJibXr8bvwUAUparCwlvdbH6dvEOfou0/gCFQsHUfQrSDv+MuSUMAe8jzKE4qW
|
||||
+jK+xQU9a03GUnKHkkle+Q0pX/g6jXZ7r1/xAK5Do2kQ+X5xK9cipRgEKwIDAQAB
|
||||
AoGAD+onAtVye4ic7VR7V50DF9bOnwRwNXrARcDhq9LWNRrRGElESYYTQ6EbatXS
|
||||
3MCyjjX2eMhu/aF5YhXBwkppwxg+EOmXeh+MzL7Zh284OuPbkglAaGhV9bb6/5Cp
|
||||
uGb1esyPbYW+Ty2PC0GSZfIXkXs76jXAu9TOBvD0ybc2YlkCQQDywg2R/7t3Q2OE
|
||||
2+yo382CLJdrlSLVROWKwb4tb2PjhY4XAwV8d1vy0RenxTB+K5Mu57uVSTHtrMK0
|
||||
GAtFr833AkEA6avx20OHo61Yela/4k5kQDtjEf1N0LfI+BcWZtxsS3jDM3i1Hp0K
|
||||
Su5rsCPb8acJo5RO26gGVrfAsDcIXKC+bQJAZZ2XIpsitLyPpuiMOvBbzPavd4gY
|
||||
6Z8KWrfYzJoI/Q9FuBo6rKwl4BFoToD7WIUS+hpkagwWiz+6zLoX1dbOZwJACmH5
|
||||
fSSjAkLRi54PKJ8TFUeOP15h9sQzydI8zJU+upvDEKZsZc/UhT/SySDOxQ4G/523
|
||||
Y0sz/OZtSWcol/UMgQJALesy++GdvoIDLfJX5GBQpuFgFenRiRDabxrE9MNUZ2aP
|
||||
FaFp+DyAe+b4nDwuJaW2LURbr8AEZga7oQj0uYxcYw==
|
||||
-----END RSA PRIVATE KEY-----`;
|
||||
const esKey = `-----BEGIN PRIVATE KEY-----
|
||||
MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQgevZzL1gdAFr88hb2
|
||||
OF/2NxApJCzGCEDdfSp6VQO30hyhRANCAAQRWz+jn65BtOMvdyHKcvjBeBSDZH2r
|
||||
1RTwjmYSi9R/zpBnuQ4EiMnCqfMPWiZqB4QdbAd0E7oH50VpuZ1P087G
|
||||
-----END PRIVATE KEY-----`;
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "JWT Verify: HS",
|
||||
input: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.0ha6-j4FwvEIKPVZ-hf3S_R9Hy_UtXzq4dnedXcUrXk",
|
||||
expectedOutput: outputObject,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Verify",
|
||||
args: [hsKey],
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "JWT Verify: RS",
|
||||
input: "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.MjEJhtZk2nXzigi24piMzANmrj3mILHJcDl0xOjl5a8EgdKVL1oaMEjTkMQp5RA8YrqeRBFaX-BGGCKOXn5zPY1DJwWsBUyN9C-wGR2Qye0eogH_3b4M9EW00TPCUPXm2rx8URFj7Wg9VlsmrGzLV2oKkPgkVxuFSxnpO3yjn1Y",
|
||||
expectedOutput: invalidAlgorithm,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Verify",
|
||||
args: [rsKey],
|
||||
}
|
||||
],
|
||||
},
|
||||
{
|
||||
name: "JWT Verify: ES",
|
||||
input: "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJTdHJpbmciOiJTb21lU3RyaW5nIiwiTnVtYmVyIjo0MiwiaWF0IjoxfQ.WkECT51jSfpRkcpQ4x0h5Dwe7CFBI6u6Et2gWp91HC7mpN_qCFadRpsvJLtKubm6cJTLa68xtei0YrDD8fxIUA",
|
||||
expectedOutput: invalidAlgorithm,
|
||||
recipeConfig: [
|
||||
{
|
||||
op: "JWT Verify",
|
||||
args: [esKey],
|
||||
}
|
||||
],
|
||||
}
|
||||
]);
|
||||
56
test/tests/operations/ParseTLV.mjs
Normal file
56
test/tests/operations/ParseTLV.mjs
Normal file
@@ -0,0 +1,56 @@
|
||||
/**
|
||||
* Parse TLV tests.
|
||||
*
|
||||
* @author gchq77703 []
|
||||
* @copyright Crown Copyright 2018
|
||||
* @license Apache-2.0
|
||||
*/
|
||||
|
||||
import TestRegister from "../../TestRegister";
|
||||
|
||||
TestRegister.addTests([
|
||||
{
|
||||
name: "Parse TLV: LengthValue",
|
||||
input: "\x05\x48\x6f\x75\x73\x65\x04\x72\x6f\x6f\x6d\x04\x64\x6f\x6f\x72",
|
||||
expectedOutput: JSON.stringify([{"length": 5, "value": [72, 111, 117, 115, 101]}, {"length": 4, "value": [114, 111, 111, 109]}, {"length": 4, "value": [100, 111, 111, 114]}], null, 4),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Parse TLV",
|
||||
"args": [0, 1, false]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Parse TLV: LengthValue with BER",
|
||||
input: "\x05\x48\x6f\x75\x73\x65\x04\x72\x6f\x6f\x6d\x04\x64\x6f\x6f\x72",
|
||||
expectedOutput: JSON.stringify([{"length": 5, "value": [72, 111, 117, 115, 101]}, {"length": 4, "value": [114, 111, 111, 109]}, {"length": 4, "value": [100, 111, 111, 114]}], null, 4),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Parse TLV",
|
||||
"args": [0, 4, true] // length value is patently wrong, should be ignored by BER.
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Parse TLV: KeyLengthValue",
|
||||
input: "\x04\x05\x48\x6f\x75\x73\x65\x05\x04\x72\x6f\x6f\x6d\x42\x04\x64\x6f\x6f\x72",
|
||||
expectedOutput: JSON.stringify([{"key": [4], "length": 5, "value": [72, 111, 117, 115, 101]}, {"key": [5], "length": 4, "value": [114, 111, 111, 109]}, {"key": [66], "length": 4, "value": [100, 111, 111, 114]}], null, 4),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Parse TLV",
|
||||
"args": [1, 1, false]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "Parse TLV: KeyLengthValue with BER",
|
||||
input: "\x04\x05\x48\x6f\x75\x73\x65\x05\x04\x72\x6f\x6f\x6d\x42\x04\x64\x6f\x6f\x72",
|
||||
expectedOutput: JSON.stringify([{"key": [4], "length": 5, "value": [72, 111, 117, 115, 101]}, {"key": [5], "length": 4, "value": [114, 111, 111, 109]}, {"key": [66], "length": 4, "value": [100, 111, 111, 114]}], null, 4),
|
||||
recipeConfig: [
|
||||
{
|
||||
"op": "Parse TLV",
|
||||
"args": [1, 4, true] // length value is patently wrong, should be ignored by BER.
|
||||
}
|
||||
]
|
||||
}
|
||||
]);
|
||||
@@ -30,6 +30,9 @@ const banner = `/**
|
||||
* limitations under the License.
|
||||
*/`;
|
||||
|
||||
const vendorCSS = new ExtractTextPlugin("vendor.css");
|
||||
const projectCSS = new ExtractTextPlugin("styles.css");
|
||||
|
||||
module.exports = {
|
||||
plugins: [
|
||||
new webpack.ProvidePlugin({
|
||||
@@ -42,7 +45,8 @@ module.exports = {
|
||||
raw: true,
|
||||
entryOnly: true
|
||||
}),
|
||||
new ExtractTextPlugin("styles.css")
|
||||
vendorCSS,
|
||||
projectCSS
|
||||
],
|
||||
resolve: {
|
||||
alias: {
|
||||
@@ -67,7 +71,7 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
test: /\.css$/,
|
||||
use: ExtractTextPlugin.extract({
|
||||
use: projectCSS.extract({
|
||||
use: [
|
||||
{ loader: "css-loader" },
|
||||
{ loader: "postcss-loader" },
|
||||
@@ -76,7 +80,7 @@ module.exports = {
|
||||
},
|
||||
{
|
||||
test: /\.scss$/,
|
||||
use: ExtractTextPlugin.extract({
|
||||
use: vendorCSS.extract({
|
||||
use: [
|
||||
{ loader: "css-loader" },
|
||||
{ loader: "sass-loader" }
|
||||
@@ -113,7 +117,11 @@ module.exports = {
|
||||
chunks: false,
|
||||
modules: false,
|
||||
entrypoints: false,
|
||||
warningsFilter: [/source-map/, /dependency is an expression/],
|
||||
warningsFilter: [
|
||||
/source-map/,
|
||||
/dependency is an expression/,
|
||||
/export 'default'/
|
||||
],
|
||||
},
|
||||
node: {
|
||||
fs: "empty"
|
||||
|
||||
Reference in New Issue
Block a user