diff --git a/README.md b/README.md index a1dae134..93f378ed 100644 --- a/README.md +++ b/README.md @@ -295,6 +295,13 @@ javascript-obfuscator ./dist [options] javascript-obfuscator ./dist --output ./dist/obfuscated [options] // creates a folder structure with obfuscated files under `./dist/obfuscated` path + +#### Obfuscate directory recursively and overwrite original files + +Usage: +```sh +javascript-obfuscator ./dist --dangerously-overwrite true [options] +// obfuscates all `.js` files under `./dist` directory and overwrites the original files with obfuscated content ``` Obfuscation of all `.js` files under input directory. If this directory contains already obfuscated files with `-obfuscated` postfix - these files will ignored. @@ -457,6 +464,7 @@ Following options are available for the JS Obfuscator: --target [browser, browser-no-eval, node] --transform-object-keys --unicode-escape-sequence + --dangerously-overwrite ``` diff --git a/src/cli/JavaScriptObfuscatorCLI.ts b/src/cli/JavaScriptObfuscatorCLI.ts index 2a10bd11..a0c1281b 100644 --- a/src/cli/JavaScriptObfuscatorCLI.ts +++ b/src/cli/JavaScriptObfuscatorCLI.ts @@ -445,6 +445,11 @@ export class JavaScriptObfuscatorCLI implements IInitializable { 'Allows to enable/disable string conversion to unicode escape sequence', BooleanSanitizer ) + .option( + '--dangerously-overwrite ', + 'Enables overwriting the original files with obfuscated content', + BooleanSanitizer + ) .parse(this.rawArguments); } @@ -463,7 +468,9 @@ export class JavaScriptObfuscatorCLI implements IInitializable { */ private processSourceCodeData (sourceCodeData: IFileData[]): void { sourceCodeData.forEach(({ filePath, content }: IFileData, index: number) => { - const outputCodePath: string = this.obfuscatedCodeFileUtils.getOutputCodePath(filePath); + const outputCodePath: string = this.inputCLIOptions.dangerouslyOverwrite + ? filePath + : this.obfuscatedCodeFileUtils.getOutputCodePath(filePath); try { Logger.log( diff --git a/src/cli/utils/ObfuscatedCodeFileUtils.ts b/src/cli/utils/ObfuscatedCodeFileUtils.ts index de7824f2..08775da4 100644 --- a/src/cli/utils/ObfuscatedCodeFileUtils.ts +++ b/src/cli/utils/ObfuscatedCodeFileUtils.ts @@ -36,6 +36,10 @@ export class ObfuscatedCodeFileUtils { * @returns {string} */ public getOutputCodePath (filePath: string): string { + if (this.options.dangerouslyOverwrite) { + return this.getOutputCodePathForOverwrite(filePath); + } + const normalizedFilePath: string = path.normalize(filePath); const normalizedRawOutputPath: string | null = this.options.output ? path.normalize(this.options.output) @@ -146,4 +150,12 @@ export class ObfuscatedCodeFileUtils { encoding: JavaScriptObfuscatorCLI.encoding }); } + /** + * @param {string} filePath + * @returns {string} + */ + private getOutputCodePathForOverwrite (filePath: string): string { + return path.normalize(filePath); + } + } diff --git a/src/interfaces/options/ICLIOptions.ts b/src/interfaces/options/ICLIOptions.ts index 8fdc4cec..1b7ab92b 100644 --- a/src/interfaces/options/ICLIOptions.ts +++ b/src/interfaces/options/ICLIOptions.ts @@ -1,6 +1,7 @@ import { IOptions } from './IOptions'; export interface ICLIOptions extends IOptions { + readonly dangerouslyOverwrite: boolean; readonly config: string; readonly exclude: string[]; readonly identifierNamesCachePath: string; diff --git a/test/functional-tests/cli/JavaScriptObfuscatorCLI.spec.ts b/test/functional-tests/cli/JavaScriptObfuscatorCLI.spec.ts index 0757aa81..3faedec3 100644 --- a/test/functional-tests/cli/JavaScriptObfuscatorCLI.spec.ts +++ b/test/functional-tests/cli/JavaScriptObfuscatorCLI.spec.ts @@ -527,6 +527,74 @@ describe('JavaScriptObfuscatorCLI', function (): void { }); }); }); + + describe('Variant #5: obfuscation of directory with `--dangerously-overwrite` option', () => { + const directoryPath: string = path.join(fixturesDirName, 'directory-obfuscation'); + const outputFileName1: string = 'foo.js'; + const outputFileName2: string = 'bar.js'; + const outputFileName3: string = 'baz.js'; + const readFileEncoding = 'utf8'; + const regExp1: RegExp = /^var a1_0x(\w){4,6} *= *0x1;$/; + const regExp2: RegExp = /^var a0_0x(\w){4,6} *= *0x2;$/; + + let outputFixturesFilePath1: string, + outputFixturesFilePath2: string, + outputFixturesFilePath3: string, + isFileExist1: boolean, + isFileExist2: boolean, + isFileExist3: boolean, + fileContent1: string, + fileContent2: string; + + before(() => { + outputFixturesFilePath1 = path.join(directoryPath, outputFileName1); + outputFixturesFilePath2 = path.join(directoryPath, outputFileName2); + outputFixturesFilePath3 = path.join(directoryPath, outputFileName3); + + JavaScriptObfuscatorCLI.obfuscate([ + 'node', + 'javascript-obfuscator', + directoryPath, + '--dangerously-overwrite', + 'true', + '--rename-globals', + 'true' + ]); + + isFileExist1 = fs.existsSync(outputFixturesFilePath1); + isFileExist2 = fs.existsSync(outputFixturesFilePath2); + isFileExist3 = fs.existsSync(outputFixturesFilePath3); + + fileContent1 = fs.readFileSync(outputFixturesFilePath1, readFileEncoding); + fileContent2 = fs.readFileSync(outputFixturesFilePath2, readFileEncoding); + }); + + it(`should overwrite file \`${outputFileName1}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => { + assert.equal(isFileExist1, true); + }); + + it(`should overwrite file \`${outputFileName2}\` with obfuscated code in \`${fixturesDirName}\` directory`, () => { + assert.equal(isFileExist2, true); + }); + + it(`shouldn't create file \`${outputFileName3}\` in \`${fixturesDirName}\` directory`, () => { + assert.equal(isFileExist3, false); + }); + + it(`match #1: should overwrite file with obfuscated code with prefixed identifier`, () => { + assert.match(fileContent1, regExp1); + }); + + it(`match #2: should overwrite file with obfuscated code with prefixed identifier`, () => { + assert.match(fileContent2, regExp2); + }); + + after(() => { + // instead recreate foo and bar files exactly as they were instead of deleting them + fs.writeFileSync(outputFixturesFilePath1, 'var foo = 1;'); + fs.writeFileSync(outputFixturesFilePath2, 'var bar = 2;'); + }); + }); }); describe('`--sourceMap` option is set', () => {