From b763711ee7cf397fc2db398c55ec7f1cc65de485 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bjo=CC=88rn=20Ganslandt?= Date: Wed, 17 Jun 2020 10:20:47 +0200 Subject: [PATCH 1/4] Rewrite in typescript --- .prettierrc | 4 + index.js | 46 +---- package-lock.json | 176 ++++++++++++++---- package.json | 63 ++++--- src/index.ts | 54 ++++++ .../options-schema.json | 0 tsconfig.json | 20 ++ 7 files changed, 252 insertions(+), 111 deletions(-) create mode 100644 .prettierrc create mode 100644 src/index.ts rename options-schema.json => src/options-schema.json (100%) create mode 100644 tsconfig.json diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 0000000..febe9b5 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,4 @@ + +{ + "printWidth": 80 +} diff --git a/index.js b/index.js index db559cc..6ec6b04 100644 --- a/index.js +++ b/index.js @@ -1,46 +1,6 @@ -const crypto = require("crypto"); -const loaderUtils = require("loader-utils"); -const validateOptions = require("schema-utils"); -const schema = require("./options-schema.json"); +var loader = require('./dist'); -const defaultOptions = { - algorithm: "cast5-cbc", - salt: "nodecipher", - digest: "sha1", - iterations: 1000, - keylen: 512, -}; - -module.exports = function decrypt(ciphertext) { - // Result can be cached - if (this.cacheable) this.cacheable(); - - // Get and validate options - const options = Object.assign( - {}, - defaultOptions, - loaderUtils.getOptions(this), - ); - - validateOptions(schema, options, "Decryption Loader"); - - // Derive Key from password - const key = crypto.pbkdf2Sync( - options.password, - options.salt, - options.iterations, - options.keylen, - options.digest, - ); - - // Run Decryption - const decipher = crypto.createDecipher( - options.algorithm, - key.toString("hex"), - ); - - return Buffer.concat([decipher.update(ciphertext), decipher.final()]); -}; +module.exports = loader; // This loader works on buffers -module.exports.raw = true; +module.exports.raw = true; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index db7cc86..433a87e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "decryption-loader", - "version": "1.1.8", + "version": "2.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -888,6 +888,12 @@ "@sinonjs/commons": "^1.7.0" } }, + "@types/anymatch": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@types/anymatch/-/anymatch-1.3.1.tgz", + "integrity": "sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA==", + "dev": true + }, "@types/babel__core": { "version": "7.1.7", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.7.tgz", @@ -991,6 +997,16 @@ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.4.tgz", "integrity": "sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA==" }, + "@types/loader-utils": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@types/loader-utils/-/loader-utils-2.0.1.tgz", + "integrity": "sha512-X3jTNi/I2AEd2WrHdSqRppPkYzWkRMNGxJzeMwS0o3hVi8ZB6JCnf/XyQmqpUuCidld5lC/1VxVgTktEweRK+w==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/webpack": "*" + } + }, "@types/minimatch": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", @@ -1015,12 +1031,82 @@ "integrity": "sha512-boy4xPNEtiw6N3abRhBi/e7hNvy3Tt8E9ZRAQrwAGzoCGZS/1wjo9KY7JHhnfnEsG5wSjDbymCozUM9a3ea7OQ==", "dev": true }, + "@types/source-list-map": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/@types/source-list-map/-/source-list-map-0.1.2.tgz", + "integrity": "sha512-K5K+yml8LTo9bWJI/rECfIPrGgxdpeNbj+d53lwN4QjW1MCwlkhUms+gtdzigTeUyBr09+u8BwOIY3MXvHdcsA==", + "dev": true + }, "@types/stack-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-1.0.1.tgz", "integrity": "sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw==", "dev": true }, + "@types/tapable": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/tapable/-/tapable-1.0.6.tgz", + "integrity": "sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==", + "dev": true + }, + "@types/uglify-js": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.2.tgz", + "integrity": "sha512-d6dIfpPbF+8B7WiCi2ELY7m0w1joD8cRW4ms88Emdb2w062NeEpbNCeWwVCgzLRpVG+5e74VFSg4rgJ2xXjEiQ==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@types/webpack": { + "version": "4.41.17", + "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.17.tgz", + "integrity": "sha512-6FfeCidTSHozwKI67gIVQQ5Mp0g4X96c2IXxX75hYEQJwST/i6NyZexP//zzMOBb+wG9jJ7oO8fk9yObP2HWAw==", + "dev": true, + "requires": { + "@types/anymatch": "*", + "@types/node": "*", + "@types/tapable": "*", + "@types/uglify-js": "*", + "@types/webpack-sources": "*", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "@types/webpack-sources": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@types/webpack-sources/-/webpack-sources-1.4.0.tgz", + "integrity": "sha512-c88dKrpSle9BtTqR6ifdaxu1Lvjsl3C5OsfvuUbUwdXymshv1TkufUAXBajCCUM/f/TmnkZC/Esb03MinzSiXQ==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/source-list-map": "*", + "source-map": "^0.7.3" + }, + "dependencies": { + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + } + } + }, "@types/yargs": { "version": "15.0.5", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.5.tgz", @@ -1286,7 +1372,7 @@ }, "ansi-escapes": { "version": "4.3.1", - "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", "dev": true, "requires": { @@ -1763,7 +1849,7 @@ }, "babel-plugin-istanbul": { "version": "6.0.0", - "resolved": "http://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.0.0.tgz", "integrity": "sha512-AF55rZXpe7trmEylbaE1Gv54wn6rwU03aptvRoVIGP8YykoSxqdVLV1TfwflBCE/QtHmqtP8SWlTENqbK8GCSQ==", "dev": true, "requires": { @@ -1987,7 +2073,7 @@ }, "browserify-aes": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", "dev": true, "requires": { @@ -2024,7 +2110,7 @@ }, "browserify-rsa": { "version": "4.0.1", - "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, "requires": { @@ -2067,7 +2153,7 @@ }, "buffer": { "version": "4.9.2", - "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", "dev": true, "requires": { @@ -2175,7 +2261,7 @@ }, "callsites": { "version": "3.1.0", - "resolved": "http://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", "dev": true }, @@ -2427,7 +2513,7 @@ }, "concat-stream": { "version": "1.6.2", - "resolved": "http://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", "dev": true, "requires": { @@ -2496,7 +2582,7 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", "dev": true, "requires": { @@ -2509,7 +2595,7 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", "dev": true, "requires": { @@ -2780,7 +2866,7 @@ }, "diffie-hellman": { "version": "5.0.3", - "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, "requires": { @@ -2982,7 +3068,7 @@ }, "events": { "version": "3.1.0", - "resolved": "http://registry.npmjs.org/events/-/events-3.1.0.tgz", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", "dev": true }, @@ -3405,7 +3491,7 @@ }, "fs-extra": { "version": "0.26.7", - "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", "dev": true, "requires": { @@ -3999,7 +4085,7 @@ }, "get-stream": { "version": "4.1.0", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", "dev": true, "requires": { @@ -4389,7 +4475,7 @@ }, "inquirer": { "version": "0.11.4", - "resolved": "http://registry.npmjs.org/inquirer/-/inquirer-0.11.4.tgz", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.11.4.tgz", "integrity": "sha1-geM3ToNhvq/y2XAWIG01nQsy+k0=", "dev": true, "requires": { @@ -4410,7 +4496,7 @@ "dependencies": { "ansi-escapes": { "version": "1.4.0", - "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", "dev": true }, @@ -4866,7 +4952,7 @@ }, "get-stream": { "version": "5.1.0", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", "dev": true, "requires": { @@ -5060,7 +5146,7 @@ }, "jest-get-type": { "version": "26.0.0", - "resolved": "http://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-26.0.0.tgz", "integrity": "sha512-zRc1OAPnnws1EVfykXOj19zo2EMw5Hi6HLbFCSjpuJiXtOWAYIjNsHVSbpQ8bDX7L5BGYGI8m+HmKdjHYFF0kg==", "dev": true }, @@ -5617,7 +5703,7 @@ }, "jsesc": { "version": "2.5.2", - "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, @@ -5646,7 +5732,7 @@ }, "json5": { "version": "2.1.3", - "resolved": "http://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", "dev": true, "requires": { @@ -5655,7 +5741,7 @@ }, "jsonfile": { "version": "2.4.0", - "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "dev": true, "requires": { @@ -5942,7 +6028,7 @@ }, "minimist": { "version": "1.2.5", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "mississippi": { @@ -5986,7 +6072,7 @@ }, "mkdirp": { "version": "0.5.5", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "dev": true, "requires": { @@ -6015,7 +6101,7 @@ }, "mute-stream": { "version": "0.0.5", - "resolved": "http://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", "dev": true }, @@ -6182,7 +6268,7 @@ }, "yargs": { "version": "3.32.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", "dev": true, "requires": { @@ -6491,7 +6577,7 @@ }, "parse-asn1": { "version": "5.1.5", - "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", "dev": true, "requires": { @@ -6529,7 +6615,7 @@ }, "path-browserify": { "version": "0.0.1", - "resolved": "http://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", "dev": true }, @@ -6547,7 +6633,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", "dev": true }, @@ -6624,6 +6710,12 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prettier": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "dev": true + }, "pretty-format": { "version": "26.0.1", "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-26.0.1.tgz", @@ -7044,7 +7136,7 @@ }, "resolve": { "version": "1.17.0", - "resolved": "http://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", "dev": true, "requires": { @@ -7157,7 +7249,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { @@ -7273,7 +7365,7 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", "dev": true, "requires": { @@ -7597,7 +7689,7 @@ }, "stream-browserify": { "version": "2.0.2", - "resolved": "http://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", "dev": true, "requires": { @@ -7657,7 +7749,7 @@ }, "string_decoder": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", "dev": true, "requires": { @@ -7689,7 +7781,7 @@ }, "strip-eof": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, @@ -7842,7 +7934,7 @@ }, "through": { "version": "2.3.8", - "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, @@ -7953,7 +8045,7 @@ }, "tty-browserify": { "version": "0.0.0", - "resolved": "http://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", "dev": true }, @@ -8008,6 +8100,12 @@ "is-typedarray": "^1.0.0" } }, + "typescript": { + "version": "3.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.5.tgz", + "integrity": "sha512-hSAifV3k+i6lEoCJ2k6R2Z/rp/H3+8sdmcn5NrS3/3kE7+RyZXm9aqvxWqjEXHAd8b0pShatpcdMTvEdvAJltQ==", + "dev": true + }, "union-value": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", @@ -8215,7 +8313,7 @@ }, "vm-browserify": { "version": "1.1.2", - "resolved": "http://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", "dev": true }, @@ -8302,7 +8400,7 @@ }, "json5": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", "dev": true, "requires": { @@ -8528,7 +8626,7 @@ }, "yargs": { "version": "15.3.1", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.3.1.tgz", "integrity": "sha512-92O1HWEjw27sBfgmXiixJWT5hRBp2eobqXicLtPBIDBhYB+1HpwZlXmbW2luivBJHBzki+7VyCLRtAkScbTBQA==", "dev": true, "requires": { diff --git a/package.json b/package.json index d609979..815516f 100644 --- a/package.json +++ b/package.json @@ -1,31 +1,36 @@ { - "name": "decryption-loader", - "version": "1.1.8", - "description": "Webpack loader that decrypts assets encrypted by node-cipher", - "repository": "https://github.com/Ansimorph/decryption-loader/", - "main": "index.js", - "scripts": { - "test": "jest" - }, - "author": "Björn Ganslandt", - "license": "MIT", - "private": false, - "keywords": [ - "webpack", - "decrypt", - "cipher", - "loader" - ], - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^2.0.1" - }, - "devDependencies": { - "del": "^5.0.0", - "jest": "^26.0.1", - "memory-fs": "^0.5.0", - "node-cipher": "^6.3.3", - "raw-loader": "^4.0.0", - "webpack": "^4.28.2" - } + "name": "decryption-loader", + "version": "2.0.0", + "description": "Webpack loader that decrypts assets encrypted by node-cipher", + "repository": "https://github.com/Ansimorph/decryption-loader/", + "main": "index.js", + "scripts": { + "build": "tsc --version && tsc", + "test": "jest" + }, + "author": "Björn Ganslandt", + "license": "MIT", + "private": false, + "keywords": [ + "webpack", + "decrypt", + "cipher", + "loader" + ], + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^2.0.1" + }, + "devDependencies": { + "@types/loader-utils": "^2.0.1", + "@types/webpack": "^4.41.17", + "del": "^5.0.0", + "jest": "^26.0.1", + "memory-fs": "^0.5.0", + "node-cipher": "^6.3.3", + "prettier": "^2.0.5", + "raw-loader": "^4.0.0", + "typescript": "^3.9.5", + "webpack": "^4.28.2" + } } diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..81931e8 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,54 @@ +import { createDecipher, pbkdf2Sync } from "crypto"; +import * as webpack from "webpack"; +import * as loaderUtils from "loader-utils"; +import validateOptions from "schema-utils"; +import validationSchema from "./options-schema.json"; +import { + Schema, + ValidationErrorConfiguration, +} from "schema-utils/declarations/validate"; + +const defaultOptions = { + password: "", + algorithm: "cast5-cbc", + salt: "nodecipher", + digest: "sha1", + iterations: 1000, + keylen: 512, +}; + +const validationErrorOptions = { + name: "Decryption Loader", +} as ValidationErrorConfiguration; + +function loader( + this: webpack.loader.LoaderContext, + ciphertext: any +): Buffer { + // Result can be cached + this.cacheable && this.cacheable(); + + // Get and validate options + const options = { + ...defaultOptions, + ...loaderUtils.getOptions(this), + }; + + validateOptions(validationSchema as Schema, options, validationErrorOptions); + + // Derive Key from password + const key = pbkdf2Sync( + options.password, + options.salt, + options.iterations, + options.keylen, + options.digest + ); + + // Run Decryption + const decipher = createDecipher(options.algorithm, key.toString("hex")); + + return Buffer.concat([decipher.update(ciphertext), decipher.final()]); +}; + +export = loader; diff --git a/options-schema.json b/src/options-schema.json similarity index 100% rename from options-schema.json rename to src/options-schema.json diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..db6194d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,20 @@ +{ + "compilerOptions": { + "target": "es2015", + "noImplicitReturns": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "suppressImplicitAnyIndexErrors": true, + "strict": true, + "module": "commonjs", + "moduleResolution": "node", + "declaration": true, + "outDir": "./dist", + "rootDir": "./src", + "declarationDir": "./dist", + "declarationMap": true, + "sourceMap": true, + "resolveJsonModule": true, + "esModuleInterop": true + } +} From bcbdd9e0ef3e6e7f40bb3c8e47e87baa84242303 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bjo=CC=88rn=20Ganslandt?= Date: Wed, 17 Jun 2020 12:26:30 +0200 Subject: [PATCH 2/4] Add CLI --- .npmignore | 58 +++++ cli.js | 2 + package-lock.json | 541 +++++++++------------------------------- package.json | 6 +- readme.md | 27 +- src/AppendInitVector.ts | 25 ++ src/cli.ts | 38 +++ src/cryptoUtils.ts | 60 +++++ src/index.ts | 40 +-- src/options-schema.json | 12 - test/index.test.js | 66 ++--- 11 files changed, 350 insertions(+), 525 deletions(-) create mode 100644 .npmignore create mode 100755 cli.js create mode 100644 src/AppendInitVector.ts create mode 100644 src/cli.ts create mode 100644 src/cryptoUtils.ts diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..621038f --- /dev/null +++ b/.npmignore @@ -0,0 +1,58 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env diff --git a/cli.js b/cli.js new file mode 100755 index 0000000..7bfd4ed --- /dev/null +++ b/cli.js @@ -0,0 +1,2 @@ +#!/usr/bin/env node +require("./dist/cli"); diff --git a/package-lock.json b/package-lock.json index 433a87e..c068b2a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -967,6 +967,16 @@ "@types/node": "*" } }, + "@types/inquirer": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/@types/inquirer/-/inquirer-6.5.0.tgz", + "integrity": "sha512-rjaYQ9b9y/VFGOpqBEXRavc3jh0a+e6evAbI31tMda8VlPaSy0AZJfXsvmIe3wklc7W6C3zCSfleuMXR7NOyXw==", + "dev": true, + "requires": { + "@types/through": "*", + "rxjs": "^6.4.0" + } + }, "@types/istanbul-lib-coverage": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.2.tgz", @@ -1049,6 +1059,15 @@ "integrity": "sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA==", "dev": true }, + "@types/through": { + "version": "0.0.30", + "resolved": "https://registry.npmjs.org/@types/through/-/through-0.0.30.tgz", + "integrity": "sha512-FvnCJljyxhPM3gkRgWmxmDZyAQSiBQQWLI0A0VFL0K7W1oRUrPJSqNO0NvTnLkBcotdlp3lKvaT0JrnyRDkzOg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/uglify-js": { "version": "3.9.2", "resolved": "https://registry.npmjs.org/@types/uglify-js/-/uglify-js-3.9.2.tgz", @@ -1387,12 +1406,6 @@ } } }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, "ansi-styles": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", @@ -2302,6 +2315,12 @@ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, "chokidar": { "version": "2.1.8", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", @@ -2397,18 +2416,18 @@ "dev": true }, "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", "dev": true, "requires": { - "restore-cursor": "^1.0.1" + "restore-cursor": "^3.1.0" } }, "cli-width": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.1.1.tgz", - "integrity": "sha1-pNKT72frt7iNSk1CwMzwDE0eNm0=", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", "dev": true }, "cliui": { @@ -2441,12 +2460,6 @@ "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", "dev": true }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, "collect-v8-coverage": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", @@ -2487,12 +2500,6 @@ "delayed-stream": "~1.0.0" } }, - "commander": { - "version": "2.17.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", - "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", - "dev": true - }, "commondir": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", @@ -2726,12 +2733,6 @@ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", "dev": true }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", @@ -3109,12 +3110,6 @@ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", "dev": true }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "dev": true - }, "expand-brackets": { "version": "2.1.4", "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", @@ -3191,6 +3186,17 @@ } } }, + "external-editor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", + "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, "extglob": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", @@ -3378,13 +3384,12 @@ "dev": true }, "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", + "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", "dev": true, "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" + "escape-string-regexp": "^1.0.5" } }, "file-uri-to-path": { @@ -3489,19 +3494,6 @@ "readable-stream": "^2.0.0" } }, - "fs-extra": { - "version": "0.26.7", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz", - "integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, "fs-write-stream-atomic": { "version": "1.0.10", "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", @@ -4201,15 +4193,6 @@ "har-schema": "^2.0.0" } }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -4467,107 +4450,45 @@ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", "dev": true }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - }, "inquirer": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.11.4.tgz", - "integrity": "sha1-geM3ToNhvq/y2XAWIG01nQsy+k0=", - "dev": true, - "requires": { - "ansi-escapes": "^1.1.0", - "ansi-regex": "^2.0.0", - "chalk": "^1.0.0", - "cli-cursor": "^1.0.1", - "cli-width": "^1.0.1", - "figures": "^1.3.5", - "lodash": "^3.3.1", - "readline2": "^1.0.1", - "run-async": "^0.1.0", - "rx-lite": "^3.1.2", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.0", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.2.0.tgz", + "integrity": "sha512-E0c4rPwr9ByePfNlTIB8z51kK1s2n6jrHuJeEHENl/sbq2G/S1auvibgEwNR4uSyiU+PiYHqSwsgGiXjG8p5ZQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "chalk": "^3.0.0", + "cli-cursor": "^3.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^3.0.0", + "lodash": "^4.17.15", + "mute-stream": "0.0.8", + "run-async": "^2.4.0", + "rxjs": "^6.5.3", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0", "through": "^2.3.6" }, "dependencies": { - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", "dev": true, "requires": { - "number-is-nan": "^1.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" } }, "lodash": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "dev": true } } }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, "ip-regex": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", @@ -5739,15 +5660,6 @@ "minimist": "^1.2.5" } }, - "jsonfile": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", - "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, "jsprim": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", @@ -5760,12 +5672,6 @@ "verror": "1.10.0" } }, - "keymirror": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/keymirror/-/keymirror-0.1.1.tgz", - "integrity": "sha1-kYiJ6hP40KQufFVyUO7nE63JXDU=", - "dev": true - }, "kind-of": { "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", @@ -5775,30 +5681,12 @@ "is-buffer": "^1.1.5" } }, - "klaw": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", - "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.9" - } - }, "kleur": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "^1.0.0" - } - }, "leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", @@ -5857,12 +5745,6 @@ "path-exists": "^3.0.0" } }, - "lodash": { - "version": "4.17.11", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", - "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", - "dev": true - }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", @@ -6100,9 +5982,9 @@ "dev": true }, "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "dev": true }, "nan": { @@ -6169,120 +6051,6 @@ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", "dev": true }, - "node-cipher": { - "version": "6.3.3", - "resolved": "https://registry.npmjs.org/node-cipher/-/node-cipher-6.3.3.tgz", - "integrity": "sha512-GL1yYULPOPDpu+4Pwb7wGgnmq0MjZEkGrxtqI1fmSo2Dke84shY2e+P4F6J+JU1ehjYFt40AC43AnW4y6RZi+g==", - "dev": true, - "requires": { - "chalk": "^1.1.1", - "commander": "^2.9.0", - "debug": "^2.2.0", - "fs-extra": "^0.26.4", - "inquirer": "^0.11.2", - "keymirror": "^0.1.1", - "lodash": "^4.0.0", - "rc": "^1.1.6", - "yargs": "^3.32.0" - }, - "dependencies": { - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wrap-ansi": "^2.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "os-locale": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", - "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, - "requires": { - "lcid": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - }, - "yargs": { - "version": "3.32.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", - "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", - "dev": true, - "requires": { - "camelcase": "^2.0.1", - "cliui": "^3.0.3", - "decamelize": "^1.1.1", - "os-locale": "^1.4.0", - "string-width": "^1.0.1", - "window-size": "^0.1.4", - "y18n": "^3.2.0" - } - } - } - }, "node-int64": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", @@ -6398,12 +6166,6 @@ "path-key": "^2.0.0" } }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, "nwsapi": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", @@ -6488,10 +6250,13 @@ } }, "onetime": { - "version": "1.1.0", - "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", + "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } }, "optionator": { "version": "0.8.3", @@ -6513,6 +6278,12 @@ "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", "dev": true }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, "p-each-series": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/p-each-series/-/p-each-series-2.1.0.tgz", @@ -6875,18 +6646,6 @@ "schema-utils": "^2.6.5" } }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - } - }, "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -6986,28 +6745,6 @@ "readable-stream": "^2.0.2" } }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "mute-stream": "0.0.5" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - } - } - }, "regex-not": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", @@ -7165,13 +6902,13 @@ "dev": true }, "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", "dev": true, "requires": { - "exit-hook": "^1.0.0", - "onetime": "^1.0.0" + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" } }, "ret": { @@ -7212,13 +6949,10 @@ "dev": true }, "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "dev": true, - "requires": { - "once": "^1.3.0" - } + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", + "dev": true }, "run-parallel": { "version": "1.1.9", @@ -7235,11 +6969,14 @@ "aproba": "^1.1.1" } }, - "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", - "dev": true + "rxjs": { + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", + "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } }, "safe-buffer": { "version": "5.1.2", @@ -7791,12 +7528,6 @@ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, "supports-color": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", @@ -7957,6 +7688,15 @@ "setimmediate": "^1.0.4" } }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, "tmpl": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", @@ -8508,12 +8248,6 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "window-size": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", - "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=", - "dev": true - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -8529,47 +8263,6 @@ "errno": "~0.1.7" } }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "^2.0.0" - } - } - } - }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -8612,12 +8305,6 @@ "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", "dev": true }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, "yallist": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", diff --git a/package.json b/package.json index 815516f..1572bee 100644 --- a/package.json +++ b/package.json @@ -4,9 +4,10 @@ "description": "Webpack loader that decrypts assets encrypted by node-cipher", "repository": "https://github.com/Ansimorph/decryption-loader/", "main": "index.js", + "bin": "./cli.js", "scripts": { "build": "tsc --version && tsc", - "test": "jest" + "test": "npm run build && jest --runInBand" }, "author": "Björn Ganslandt", "license": "MIT", @@ -22,12 +23,13 @@ "schema-utils": "^2.0.1" }, "devDependencies": { + "@types/inquirer": "^6.5.0", "@types/loader-utils": "^2.0.1", "@types/webpack": "^4.41.17", "del": "^5.0.0", + "inquirer": "^7.2.0", "jest": "^26.0.1", "memory-fs": "^0.5.0", - "node-cipher": "^6.3.3", "prettier": "^2.0.5", "raw-loader": "^4.0.0", "typescript": "^3.9.5", diff --git a/readme.md b/readme.md index 21f87ca..4dba50f 100644 --- a/readme.md +++ b/readme.md @@ -3,11 +3,11 @@ # Decryption Loader -Decrypt assets that were encrypted with [node-cipher][node-cipher-url] in webpack +Decrypt assets with webpack ## Why? -If your public repository includes files you can't share with the world, one solution is to encrypt them. [node-cipher][node-cipher-url] is a node-based cli for this purpose. Decryption-loader allows you to decrypt encrypted assets at build-time right in webpack. +If your public repository includes files you can't share with the world, one solution is to encrypt them. Decryption-loader allows you to encrypt assets via CLI and decrypt them at build-time right in webpack. ## Install @@ -15,13 +15,15 @@ If your public repository includes files you can't share with the world, one sol npm install decryption-loader ``` -To encrypt files, install [node-cipher][node-cipher-url]: +## Encryption ```bash -npm install node-cipher -g +npx decryption-loader example.txt ``` -## Usage +You will be prompted for a password and an encrypted file `example.txt.enc` is created. + +## Decryption **webpack.config.js** @@ -47,14 +49,8 @@ Be careful: Your webpack configuration file is probably not a safe place to keep ## Options -Decryption loader mirrors the [options available in node-cipher](https://github.com/nathanbuchar/node-cipher/blob/master/docs/using-the-node-js-api.md#options): - - **`password`** (string) _required_: The password used to derive the encryption key -- **`algorithm`** (string): The algorithm used to encrypt the data. Run `nodecipher -A` for a complete list of available algorithms. Default is _cast5_ -- **`salt`** (string): The salt used to derive the encryption key. Default is _nodecipher_ -- **`iterations`** (number): The number of iterations used to derive the key. Default is _1000_ -- **`keylen`** (number): The byte length of the derived key. Default is _512_ -- **`digest`** (string): The hash function used to derive the key. Run `nodecipher -H` for a complete list of available hash algorithms Default is _sha1_ +- **`salt`** (string): The salt used to derive the encryption key. Default is _secure_ ## An Example @@ -63,7 +59,7 @@ Decryption loader mirrors the [options available in node-cipher](https://github. Say you have `font.woff`, a commercial font that you want to include in your public repository, but can't because of licensing issues. Let's encrypt it to solve this problem: ```bash -nodecipher enc font.woff font.woff.cast5 -p password +npx decryption-loader font.woff ``` ### 2: Store password @@ -106,7 +102,7 @@ module.exports = { module: { rules: [ { - test: /\.(cast5)$/, + test: /\.(enc)$/, use: [ { loader: "file-loader", @@ -125,8 +121,7 @@ module.exports = { }; ``` -And we're done. The encrypted file is now decrypted and then processed by file-loader as `font.woff`. You can reference the encrypted file `font.woff.cast5` in your CSS like a normal font file. +And we're done. The encrypted file is now decrypted and then processed by file-loader as `font.woff`. You can reference the encrypted file `font.woff.enc` in your CSS like a normal font file. [npm]: https://img.shields.io/npm/v/decryption-loader.svg [npm-url]: https://npmjs.com/package/decryption-loader -[node-cipher-url]: https://www.npmjs.com/package/node-cipher diff --git a/src/AppendInitVector.ts b/src/AppendInitVector.ts new file mode 100644 index 0000000..cdbfe06 --- /dev/null +++ b/src/AppendInitVector.ts @@ -0,0 +1,25 @@ +/* Taken from https://medium.com/@brandonstilson/lets-encrypt-files-with-node-85037bea8c0e */ + +import { Transform, TransformOptions } from "stream"; + +class AppendInitVect extends Transform { + private initVector: Buffer; + private appended: boolean; + + constructor(initVector: Buffer, options?: TransformOptions) { + super(options); + this.initVector = initVector; + this.appended = false; + } + + _transform(chunk: any, _encoding: string, callback: Function) { + if (!this.appended) { + this.push(this.initVector); + this.appended = true; + } + this.push(chunk); + callback(); + } +} + +export = AppendInitVect; diff --git a/src/cli.ts b/src/cli.ts new file mode 100644 index 0000000..0292813 --- /dev/null +++ b/src/cli.ts @@ -0,0 +1,38 @@ +import inquirer from "inquirer"; +import { encryptFile } from "./cryptoUtils"; + +const fileName = process.argv[2]; + +function cannotBeEmpty(value: string) { + if (value && value !== "") { + return true; + } + + return "Password cannot be empty"; +} + +function fail() { + console.log("Usage: node cli.ts FILENAME"); + process.exit(1); +} + +function main() { + if (!fileName) { + fail(); + } + + inquirer + .prompt([ + { + type: "password", + message: "Enter a password", + name: "password", + validate: cannotBeEmpty, + }, + ]) + .then((answers) => { + encryptFile(fileName, answers.password); + }); +} + +main(); diff --git a/src/cryptoUtils.ts b/src/cryptoUtils.ts new file mode 100644 index 0000000..c76294f --- /dev/null +++ b/src/cryptoUtils.ts @@ -0,0 +1,60 @@ +import { + pbkdf2Sync, + BinaryLike, + createDecipheriv, + createCipheriv, + randomBytes, +} from "crypto"; +import { createReadStream, createWriteStream } from "fs"; +import * as path from "path"; +import AppendInitVector from "./AppendInitVector"; + +const ITERATIONS = 1000; +const KEY_LENGTH = 32; +const DIGEST = "sha1"; +const CIPHER = "aes-256-cbc"; +const DEFAULT_SALT = "secure"; +const IV_LENGTH = 16; + +export function getKey( + password: BinaryLike, + salt: BinaryLike = DEFAULT_SALT +): Buffer { + return pbkdf2Sync(password, salt, ITERATIONS, KEY_LENGTH, DIGEST); +} + +export function getDecipher(key: Buffer, iv: Buffer) { + return createDecipheriv(CIPHER, key, iv); +} + +export function getCipher(key: Buffer, iv: Buffer) { + return createCipheriv(CIPHER, key, iv); +} + +export function getIVFromBuffer(buffer: Buffer): Buffer { + const iv = Buffer.alloc(IV_LENGTH); + buffer.copy(iv, 0, 0, IV_LENGTH); + + return iv; +} + +export function getCipherTextFromBuffer(buffer: Buffer): Buffer { + const ciphertext = Buffer.alloc(IV_LENGTH); + buffer.copy(ciphertext, 0, IV_LENGTH, buffer.length); + + return ciphertext; +} + +export function encryptFile(file: string, key: string, salt?: string) { + // Generate a secure, pseudo random initialization vector. + const initVector = randomBytes(IV_LENGTH); + + // Generate a cipher key from the password. + const readStream = createReadStream(file); + const cipher = getCipher(getKey(key, salt), initVector); + const appendInitVect = new AppendInitVector(initVector); + // Create a write stream with a different file extension. + const writeStream = createWriteStream(path.join(file + ".enc")); + + readStream.pipe(cipher).pipe(appendInitVect).pipe(writeStream); +} diff --git a/src/index.ts b/src/index.ts index 81931e8..4dc9777 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,4 +1,3 @@ -import { createDecipher, pbkdf2Sync } from "crypto"; import * as webpack from "webpack"; import * as loaderUtils from "loader-utils"; import validateOptions from "schema-utils"; @@ -7,48 +6,33 @@ import { Schema, ValidationErrorConfiguration, } from "schema-utils/declarations/validate"; - -const defaultOptions = { - password: "", - algorithm: "cast5-cbc", - salt: "nodecipher", - digest: "sha1", - iterations: 1000, - keylen: 512, -}; +import { getKey, getDecipher, getIVFromBuffer, getCipherTextFromBuffer } from "./cryptoUtils"; const validationErrorOptions = { name: "Decryption Loader", } as ValidationErrorConfiguration; -function loader( - this: webpack.loader.LoaderContext, - ciphertext: any -): Buffer { +interface Options { + salt?: string, + password: string +} + +function loader(this: webpack.loader.LoaderContext, content: any): Buffer { // Result can be cached this.cacheable && this.cacheable(); // Get and validate options - const options = { - ...defaultOptions, - ...loaderUtils.getOptions(this), - }; + const options = loaderUtils.getOptions(this) as unknown as Options; validateOptions(validationSchema as Schema, options, validationErrorOptions); // Derive Key from password - const key = pbkdf2Sync( - options.password, - options.salt, - options.iterations, - options.keylen, - options.digest - ); + const key = getKey(options.password, options.salt); // Run Decryption - const decipher = createDecipher(options.algorithm, key.toString("hex")); + const decipher = getDecipher(key, getIVFromBuffer(content)); - return Buffer.concat([decipher.update(ciphertext), decipher.final()]); -}; + return Buffer.concat([decipher.update(getCipherTextFromBuffer(content)), decipher.final()]); +} export = loader; diff --git a/src/options-schema.json b/src/options-schema.json index 954f6b2..97d16f4 100644 --- a/src/options-schema.json +++ b/src/options-schema.json @@ -4,20 +4,8 @@ "password": { "type": "string" }, - "algorithm": { - "type": "string" - }, "salt": { "type": "string" - }, - "digest": { - "type": "string" - }, - "iterations": { - "type": "number" - }, - "keylen": { - "type": "number" } }, "additionalProperties": false diff --git a/test/index.test.js b/test/index.test.js index 22586ab..d6c1405 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -1,50 +1,36 @@ const compiler = require("./compiler.js"); -const nodecipher = require("node-cipher"); -const crypto = require("crypto"); +const cryptoUtils = require("../dist/cryptoUtils"); const del = require("del"); -async function enAndDecrypt(options) { - // Generate unique filename for encrypted file - const hash = crypto - .createHash("md5") - .update(JSON.stringify(options)) - .digest("hex"); - const filename = `fixture.txt.${hash}.enc`; - - // Encrypt - const nodecipherConfig = { - input: "test/fixture.txt", - output: `test/${filename}`, - }; - - nodecipher.encryptSync(Object.assign(nodecipherConfig, options)); +const FILENAME = "test/fixture.txt"; +const FILENAME_ENCRYPTED = "test/fixture.txt.enc"; - // Decrypt - const webpackConfig = { - loader: { - options: options, - }, - }; - - return compiler(`${filename}`, webpackConfig).then(stats => { - const { source } = stats.toJson().modules[0]; - expect(source).toBe("export default \"The Truth\";"); - - del.sync(`test/${filename}`); - }); +async function enAndDecrypt(options) { + // Encrypt + cryptoUtils.encryptFile(FILENAME, options.password, options.salt); + + // Decrypt + const webpackConfig = { + loader: { + options: options, + }, + }; + + return compiler("../" + FILENAME_ENCRYPTED, webpackConfig).then((stats) => { + const { source } = stats.toJson().modules[0]; + expect(source).toContain('The Truth'); + + del.sync(FILENAME_ENCRYPTED); + }); } test("Decrypt with default settings", () => { - return enAndDecrypt({ password: "passwörd" }); + return enAndDecrypt({ password: "passwörd" }); }); -test("Decrypt with non-default settings", () => { - return enAndDecrypt({ - password: "passlörd", - algorithm: "aes-128-cbc", - salt: "pepper", - iterations: 2, - keylen: 256, - digest: "md5", - }); +test("Decrypt with custom salt", () => { + return enAndDecrypt({ + password: "passlörd", + salt: "pepper", + }); }); From 446474f7f53d48db2891fafdb6267a3c21aa3b5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bjo=CC=88rn=20Ganslandt?= Date: Wed, 17 Jun 2020 13:14:42 +0200 Subject: [PATCH 3/4] Test with node 14 --- .github/workflows/nodejs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index d44f9be..996fb81 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: - node-version: [10.x, 12.x] + node-version: [10.x, 12.x, 14.x] steps: - uses: actions/checkout@v1 From ae50c70071489fe6c28369a2901ab299be7b0a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bjo=CC=88rn=20Ganslandt?= Date: Wed, 17 Jun 2020 13:42:02 +0200 Subject: [PATCH 4/4] Add integration test --- .github/workflows/nodejs.yml | 3 +- cli.js | 3 +- package-lock.json | 85 +++++++++++++----------------------- package.json | 8 ++-- readme.md | 3 +- src/cli.ts | 12 ++--- src/cryptoUtils.ts | 8 ++-- src/index.ts | 3 +- src/options-schema.json | 3 -- test/index.test.js | 63 +++++++++++++++++--------- 10 files changed, 96 insertions(+), 95 deletions(-) diff --git a/.github/workflows/nodejs.yml b/.github/workflows/nodejs.yml index 996fb81..ad68820 100644 --- a/.github/workflows/nodejs.yml +++ b/.github/workflows/nodejs.yml @@ -20,6 +20,7 @@ jobs: - name: npm install, build, and test run: | npm ci - npm test + npm run build + npm run test env: CI: true diff --git a/cli.js b/cli.js index 7bfd4ed..3501525 100755 --- a/cli.js +++ b/cli.js @@ -1,2 +1,3 @@ #!/usr/bin/env node -require("./dist/cli"); +const {main} = require("./dist/cli"); +main(); diff --git a/package-lock.json b/package-lock.json index c068b2a..f10c7af 100644 --- a/package-lock.json +++ b/package-lock.json @@ -938,8 +938,7 @@ "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", - "dev": true + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" }, "@types/events": { "version": "3.0.0", @@ -1023,6 +1022,12 @@ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", "dev": true }, + "@types/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", + "dev": true + }, "@types/node": { "version": "12.7.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-12.7.2.tgz", @@ -1393,7 +1398,6 @@ "version": "4.3.1", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.1.tgz", "integrity": "sha512-JWF7ocqNrp8u9oqpgV+wH5ftbt+cfvv+PTjOvKLT3AdYly/LmORARfEVT1iyjwN+4MqE5UmVKoAdIBqeoCHgLA==", - "dev": true, "requires": { "type-fest": "^0.11.0" }, @@ -1401,8 +1405,7 @@ "type-fest": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.11.0.tgz", - "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==", - "dev": true + "integrity": "sha512-OdjXJxnCN1AvyLSzeKIgXTXxV+99ZuXl3Hpo9XpJAv9MBcHrrJOQ5kV7ypXOuQie+AmWG25hLbiKdwYTifzcfQ==" } } }, @@ -1410,7 +1413,6 @@ "version": "4.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, "requires": { "@types/color-name": "^1.1.1", "color-convert": "^2.0.1" @@ -2318,8 +2320,7 @@ "chardet": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, "chokidar": { "version": "2.1.8", @@ -2419,7 +2420,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, "requires": { "restore-cursor": "^3.1.0" } @@ -2427,8 +2427,7 @@ "cli-width": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.1.tgz", - "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==", - "dev": true + "integrity": "sha512-GRMWDxpOB6Dgk2E5Uo+3eEBvtOOlimMmpbFiKuLFnQzYDavtLFY3K5ona41jgN/WdRZtG7utuVSVTL4HbZHGkw==" }, "cliui": { "version": "6.0.0", @@ -2480,7 +2479,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, "requires": { "color-name": "~1.1.4" } @@ -2488,8 +2486,7 @@ "color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, "combined-stream": { "version": "1.0.8", @@ -2956,8 +2953,7 @@ "emoji-regex": { "version": "8.0.0", "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==" }, "emojis-list": { "version": "3.0.0", @@ -3005,8 +3001,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "escodegen": { "version": "1.14.1", @@ -3190,7 +3185,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, "requires": { "chardet": "^0.7.0", "iconv-lite": "^0.4.24", @@ -3387,7 +3381,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz", "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==", - "dev": true, "requires": { "escape-string-regexp": "^1.0.5" } @@ -4196,8 +4189,7 @@ "has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, "has-value": { "version": "1.0.0", @@ -4338,7 +4330,6 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -4454,7 +4445,6 @@ "version": "7.2.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.2.0.tgz", "integrity": "sha512-E0c4rPwr9ByePfNlTIB8z51kK1s2n6jrHuJeEHENl/sbq2G/S1auvibgEwNR4uSyiU+PiYHqSwsgGiXjG8p5ZQ==", - "dev": true, "requires": { "ansi-escapes": "^4.2.1", "chalk": "^3.0.0", @@ -4475,7 +4465,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, "requires": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -4484,8 +4473,7 @@ "lodash": { "version": "4.17.15", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", - "dev": true + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" } } }, @@ -4584,8 +4572,7 @@ "is-fullwidth-code-point": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==" }, "is-generator-fn": { "version": "2.1.0", @@ -5884,8 +5871,7 @@ "mimic-fn": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==" }, "minimalistic-assert": { "version": "1.0.1", @@ -5961,6 +5947,12 @@ "minimist": "^1.2.5" } }, + "mock-stdin": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mock-stdin/-/mock-stdin-1.0.0.tgz", + "integrity": "sha512-tukRdb9Beu27t6dN+XztSRHq9J0B/CoAOySGzHfn8UTfmqipA5yNT/sDUEyYdAV3Hpka6Wx6kOMxuObdOex60Q==", + "dev": true + }, "move-concurrently": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", @@ -5984,8 +5976,7 @@ "mute-stream": { "version": "0.0.8", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, "nan": { "version": "2.14.1", @@ -6253,7 +6244,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.0.tgz", "integrity": "sha512-5NcSkPHhwTVFIQN+TUqXoS5+dlElHXdpAWu9I0HP20YOtIi+aZ0Ct82jdlILDxjLEAWwvm+qj1m6aEtsDVmm6Q==", - "dev": true, "requires": { "mimic-fn": "^2.1.0" } @@ -6281,8 +6271,7 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "p-each-series": { "version": "2.1.0", @@ -6905,7 +6894,6 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, "requires": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" @@ -6951,8 +6939,7 @@ "run-async": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz", - "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==", - "dev": true + "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==" }, "run-parallel": { "version": "1.1.9", @@ -6973,7 +6960,6 @@ "version": "6.5.5", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.5.tgz", "integrity": "sha512-WfQI+1gohdf0Dai/Bbmk5L5ItH5tYqm3ki2c5GdWhKjalzjg93N3avFjVStyZZz+A2Em+ZxKH5bNghw9UeylGQ==", - "dev": true, "requires": { "tslib": "^1.9.0" } @@ -6996,8 +6982,7 @@ "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, "sane": { "version": "4.1.0", @@ -7135,8 +7120,7 @@ "signal-exit": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", - "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", - "dev": true + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==" }, "sisteransi": { "version": "1.0.5", @@ -7477,7 +7461,6 @@ "version": "4.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, "requires": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", @@ -7497,7 +7480,6 @@ "version": "6.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, "requires": { "ansi-regex": "^5.0.0" }, @@ -7505,8 +7487,7 @@ "ansi-regex": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "dev": true + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" } } }, @@ -7532,7 +7513,6 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, "requires": { "has-flag": "^4.0.0" } @@ -7666,8 +7646,7 @@ "through": { "version": "2.3.8", "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "2.0.5", @@ -7692,7 +7671,6 @@ "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", - "dev": true, "requires": { "os-tmpdir": "~1.0.2" } @@ -7780,8 +7758,7 @@ "tslib": { "version": "1.11.1", "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.11.1.tgz", - "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==", - "dev": true + "integrity": "sha512-aZW88SY8kQbU7gpV19lN24LtXh/yD4ZZg6qieAJDDg+YBsJcSmLGK9QpnUjAKVG/xefmvJGd1WUmfpT/g6AJGA==" }, "tty-browserify": { "version": "0.0.0", diff --git a/package.json b/package.json index 1572bee..bbc1de4 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,7 @@ "bin": "./cli.js", "scripts": { "build": "tsc --version && tsc", - "test": "npm run build && jest --runInBand" + "test": "jest --runInBand --detectOpenHandles" }, "author": "Björn Ganslandt", "license": "MIT", @@ -20,14 +20,16 @@ ], "dependencies": { "loader-utils": "^2.0.0", - "schema-utils": "^2.0.1" + "minimist": "^1.2.5", + "schema-utils": "^2.0.1", + "inquirer": "^7.2.0" }, "devDependencies": { "@types/inquirer": "^6.5.0", "@types/loader-utils": "^2.0.1", + "@types/minimist": "^1.2.0", "@types/webpack": "^4.41.17", "del": "^5.0.0", - "inquirer": "^7.2.0", "jest": "^26.0.1", "memory-fs": "^0.5.0", "prettier": "^2.0.5", diff --git a/readme.md b/readme.md index 4dba50f..7be244e 100644 --- a/readme.md +++ b/readme.md @@ -33,7 +33,7 @@ module.exports = { module: { rules: [ { - test: /\.cast5$/, + test: /\.enc$/, loader: "decryption-loader", options: { password: "password", @@ -50,7 +50,6 @@ Be careful: Your webpack configuration file is probably not a safe place to keep ## Options - **`password`** (string) _required_: The password used to derive the encryption key -- **`salt`** (string): The salt used to derive the encryption key. Default is _secure_ ## An Example diff --git a/src/cli.ts b/src/cli.ts index 0292813..43ee65a 100644 --- a/src/cli.ts +++ b/src/cli.ts @@ -1,8 +1,7 @@ import inquirer from "inquirer"; +import minimist from "minimist"; import { encryptFile } from "./cryptoUtils"; -const fileName = process.argv[2]; - function cannotBeEmpty(value: string) { if (value && value !== "") { return true; @@ -16,9 +15,13 @@ function fail() { process.exit(1); } -function main() { +export function main() { + const argv = minimist(process.argv.slice(2)); + const fileName = argv._[0]; + if (!fileName) { fail(); + return; } inquirer @@ -32,7 +35,6 @@ function main() { ]) .then((answers) => { encryptFile(fileName, answers.password); + console.log(`Sucessfully encrypted to: ${fileName}.enc`); }); } - -main(); diff --git a/src/cryptoUtils.ts b/src/cryptoUtils.ts index c76294f..694f0c8 100644 --- a/src/cryptoUtils.ts +++ b/src/cryptoUtils.ts @@ -13,7 +13,7 @@ const ITERATIONS = 1000; const KEY_LENGTH = 32; const DIGEST = "sha1"; const CIPHER = "aes-256-cbc"; -const DEFAULT_SALT = "secure"; +const DEFAULT_SALT = "salty"; const IV_LENGTH = 16; export function getKey( @@ -39,7 +39,7 @@ export function getIVFromBuffer(buffer: Buffer): Buffer { } export function getCipherTextFromBuffer(buffer: Buffer): Buffer { - const ciphertext = Buffer.alloc(IV_LENGTH); + const ciphertext = Buffer.alloc(buffer.length - IV_LENGTH); buffer.copy(ciphertext, 0, IV_LENGTH, buffer.length); return ciphertext; @@ -52,9 +52,9 @@ export function encryptFile(file: string, key: string, salt?: string) { // Generate a cipher key from the password. const readStream = createReadStream(file); const cipher = getCipher(getKey(key, salt), initVector); - const appendInitVect = new AppendInitVector(initVector); + const appendInitVector = new AppendInitVector(initVector); // Create a write stream with a different file extension. const writeStream = createWriteStream(path.join(file + ".enc")); - readStream.pipe(cipher).pipe(appendInitVect).pipe(writeStream); + readStream.pipe(cipher).pipe(appendInitVector).pipe(writeStream); } diff --git a/src/index.ts b/src/index.ts index 4dc9777..0836510 100644 --- a/src/index.ts +++ b/src/index.ts @@ -13,7 +13,6 @@ const validationErrorOptions = { } as ValidationErrorConfiguration; interface Options { - salt?: string, password: string } @@ -27,7 +26,7 @@ function loader(this: webpack.loader.LoaderContext, content: any): Buffer { validateOptions(validationSchema as Schema, options, validationErrorOptions); // Derive Key from password - const key = getKey(options.password, options.salt); + const key = getKey(options.password); // Run Decryption const decipher = getDecipher(key, getIVFromBuffer(content)); diff --git a/src/options-schema.json b/src/options-schema.json index 97d16f4..a81d70c 100644 --- a/src/options-schema.json +++ b/src/options-schema.json @@ -3,9 +3,6 @@ "properties": { "password": { "type": "string" - }, - "salt": { - "type": "string" } }, "additionalProperties": false diff --git a/test/index.test.js b/test/index.test.js index d6c1405..557b978 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -1,36 +1,59 @@ +const path = require("path"); +const exec = require("child_process").exec; const compiler = require("./compiler.js"); -const cryptoUtils = require("../dist/cryptoUtils"); const del = require("del"); -const FILENAME = "test/fixture.txt"; -const FILENAME_ENCRYPTED = "test/fixture.txt.enc"; +const FILENAME = "./test/fixture.txt"; +const FILENAME_ENCRYPTED = "./test/fixture.txt.enc"; +const PASSWORD = "PASSWORD"; -async function enAndDecrypt(options) { - // Encrypt - cryptoUtils.encryptFile(FILENAME, options.password, options.salt); +// Calls CLI with command line args and enters password +function cli(args, password) { + const CWD = "."; - // Decrypt + return new Promise((resolve) => { + const childProcess = exec( + `node ${path.resolve("./cli.js")} ${args.join(" ")}`, + { CWD }, + (error, stdout, stderr) => { + resolve({ + code: error && error.code ? error.code : 0, + error, + stdout, + stderr, + }); + } + ); + + if (password) { + process.nextTick(() => { + childProcess.stdin.write(password + "\n"); + }); + } + }); +} + +test("Should fail without filename", async () => { + let result = await cli([]); + expect(result.code).toBe(1); +}); + +test("Should encrypt and decrypt", async () => { + // Encrypt with CLI + const result = await cli([FILENAME], PASSWORD); + expect(result.code).toBe(0); + + // Decrypt with Webpack const webpackConfig = { loader: { - options: options, + options: { password: PASSWORD }, }, }; return compiler("../" + FILENAME_ENCRYPTED, webpackConfig).then((stats) => { const { source } = stats.toJson().modules[0]; - expect(source).toContain('The Truth'); + expect(source).toContain("The Truth"); del.sync(FILENAME_ENCRYPTED); }); -} - -test("Decrypt with default settings", () => { - return enAndDecrypt({ password: "passwörd" }); -}); - -test("Decrypt with custom salt", () => { - return enAndDecrypt({ - password: "passlörd", - salt: "pepper", - }); });