IsAllowedForObfuscationTarget validator

This commit is contained in:
sanex3339
2020-01-19 22:22:50 +03:00
parent 1b1c52ef88
commit e9ddfdf81d
15 changed files with 450 additions and 13 deletions
+6 -6
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
File diff suppressed because one or more lines are too long
+1
View File
@@ -33,6 +33,7 @@
"eslint-scope": "5.0.0",
"estraverse": "4.3.0",
"eventemitter3": "4.0.0",
"fast-deep-equal": "^3.1.1",
"inversify": "5.0.1",
"js-string-escape": "1.0.1",
"md5": "2.2.1",
+2 -1
View File
@@ -1,3 +1,4 @@
export enum StringSeparator {
Dot = '.'
Dot = '.',
Comma = ',',
}
+21
View File
@@ -34,6 +34,7 @@ import { StringArrayEncoding } from '../enums/StringArrayEncoding';
import { DEFAULT_PRESET } from './presets/Default';
import { ValidationErrorsFormatter } from './ValidationErrorsFormatter';
import { IsAllowedForObfuscationTargets } from './validators/IsAllowedForObfuscationTargets';
@injectable()
export class Options implements IOptions {
@@ -104,6 +105,10 @@ export class Options implements IOptions {
@IsString({
each: true
})
@IsAllowedForObfuscationTargets([
ObfuscationTarget.Browser,
ObfuscationTarget.BrowserNoEval,
])
public readonly domainLock!: string[];
/**
@@ -198,6 +203,10 @@ export class Options implements IOptions {
* @type {boolean}
*/
@IsBoolean()
@IsAllowedForObfuscationTargets([
ObfuscationTarget.Browser,
ObfuscationTarget.BrowserNoEval,
])
public readonly sourceMap!: boolean;
/**
@@ -210,18 +219,30 @@ export class Options implements IOptions {
require_tld: false,
require_valid_protocol: true
})
@IsAllowedForObfuscationTargets([
ObfuscationTarget.Browser,
ObfuscationTarget.BrowserNoEval,
])
public readonly sourceMapBaseUrl!: string;
/**
* @type {string}
*/
@IsString()
@IsAllowedForObfuscationTargets([
ObfuscationTarget.Browser,
ObfuscationTarget.BrowserNoEval,
])
public readonly sourceMapFileName!: string;
/**
* @type {SourceMapMode}
*/
@IsIn([SourceMapMode.Inline, SourceMapMode.Separate])
@IsAllowedForObfuscationTargets([
ObfuscationTarget.Browser,
ObfuscationTarget.BrowserNoEval,
])
public readonly sourceMapMode!: TypeFromEnum<typeof SourceMapMode>;
/**
@@ -0,0 +1,54 @@
import { registerDecorator, ValidationArguments, ValidationOptions } from 'class-validator';
import { TypeFromEnum } from '@gradecam/tsenum';
import equal from 'fast-deep-equal';
import { IOptions } from '../../interfaces/options/IOptions';
import { ObfuscationTarget } from '../../enums/ObfuscationTarget';
import { StringSeparator } from '../../enums/StringSeparator';
import { DEFAULT_PRESET } from '../presets/Default';
/**
* @param {TypeFromEnum<typeof ObfuscationTarget>[]} obfuscationTargets
* @param {ValidationOptions} validationOptions
* @returns {(options: IOptions, propertyName: keyof IOptions) => void}
*/
export function IsAllowedForObfuscationTargets (
obfuscationTargets: TypeFromEnum<typeof ObfuscationTarget>[],
validationOptions?: ValidationOptions
): (options: IOptions, propertyName: keyof IOptions) => void {
return (optionsObject: IOptions, propertyName: keyof IOptions) => {
registerDecorator({
propertyName,
constraints: [obfuscationTargets],
name: 'IsAllowedForObfuscationTargets',
options: validationOptions,
target: optionsObject.constructor,
validator: {
/**
* @param value
* @param {ValidationArguments} validationArguments
* @returns {boolean}
*/
validate (value: IOptions[keyof IOptions], validationArguments: ValidationArguments): boolean {
const options: IOptions = <IOptions>validationArguments.object;
const defaultValue: IOptions[keyof IOptions] | undefined = DEFAULT_PRESET[propertyName];
const isDefaultValue: boolean = equal(value, defaultValue);
return isDefaultValue || obfuscationTargets.includes(options.target);
},
/**
* @param {ValidationArguments} validationArguments
* @returns {string}
*/
defaultMessage (validationArguments: ValidationArguments): string {
const requiredObfuscationTargetsString: string = obfuscationTargets.join(`${StringSeparator.Comma} `);
return `This option allowed only for obfuscation targets: ${requiredObfuscationTargetsString}`;
}
}
});
};
}
+3 -4
View File
@@ -1,7 +1,7 @@
'use strict';
import { NO_ADDITIONAL_NODES_PRESET } from '../../src/options/presets/NoCustomNodes';
import { IdentifierNamesGenerator } from '../../src/enums/generators/identifier-names-generators/IdentifierNamesGenerator';
import { ObfuscationTarget } from '../../src/enums/ObfuscationTarget';
(function () {
const JavaScriptObfuscator: any = require('../../index');
@@ -14,9 +14,8 @@ import { IdentifierNamesGenerator } from '../../src/enums/generators/identifier-
`,
{
...NO_ADDITIONAL_NODES_PRESET,
compact: false,
renameGlobals: true,
identifierNamesGenerator: IdentifierNamesGenerator.MangledIdentifierNamesGenerator
sourceMap: true,
target: ObfuscationTarget.Browser
}
).getObfuscatedCode();
@@ -0,0 +1,70 @@
import { assert } from 'chai';
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
import { ObfuscationTarget } from '../../../../../src/enums/ObfuscationTarget';
describe('`domainLock` IsAllowedForObfuscationTarget validator', () => {
describe('Variant #1: positive validation', () => {
describe('Variant #1: obfuscation target: `browser`', () => {
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
domainLock: ['www.example.com'],
target: ObfuscationTarget.Browser
}
).getObfuscatedCode();
});
it('should pass validation when obfuscation target is `browser`', () => {
assert.doesNotThrow(testFunc);
});
});
describe('Variant #2: obfuscation target: `node` and default value', () => {
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
domainLock: [],
target: ObfuscationTarget.Node
}
).getObfuscatedCode();
});
it('should pass validation when obfuscation target is `node` and value is default', () => {
assert.doesNotThrow(testFunc);
});
});
});
describe('Variant #2: negative validation', () => {
const expectedError: string = 'This option allowed only for obfuscation targets';
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
domainLock: ['www.example.com'],
target: ObfuscationTarget.Node
}
).getObfuscatedCode();
});
it('should not pass validation when obfuscation target is `node` and value is not default', () => {
assert.throws(testFunc, expectedError);
});
});
});
@@ -0,0 +1,70 @@
import { assert } from 'chai';
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
import { ObfuscationTarget } from '../../../../../src/enums/ObfuscationTarget';
describe('`sourceMapBaseUrl` IsAllowedForObfuscationTarget validator', () => {
describe('Variant #1: positive validation', () => {
describe('Variant #1: obfuscation target: `browser`', () => {
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
sourceMapBaseUrl: 'http://www.example.com',
target: ObfuscationTarget.Browser
}
).getObfuscatedCode();
});
it('should pass validation when obfuscation target is `browser`', () => {
assert.doesNotThrow(testFunc);
});
});
describe('Variant #2: obfuscation target: `node` and default value', () => {
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
sourceMapBaseUrl: '',
target: ObfuscationTarget.Node
}
).getObfuscatedCode();
});
it('should pass validation when obfuscation target is `node` and value is default', () => {
assert.doesNotThrow(testFunc);
});
});
});
describe('Variant #2: negative validation', () => {
const expectedError: string = 'This option allowed only for obfuscation targets';
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
sourceMapBaseUrl: 'http://www.example.com',
target: ObfuscationTarget.Node
}
).getObfuscatedCode();
});
it('should not pass validation when obfuscation target is `node` and value is not default', () => {
assert.throws(testFunc, expectedError);
});
});
});
@@ -0,0 +1,70 @@
import { assert } from 'chai';
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
import { ObfuscationTarget } from '../../../../../src/enums/ObfuscationTarget';
describe('`sourceMapFileName` IsAllowedForObfuscationTarget validator', () => {
describe('Variant #1: positive validation', () => {
describe('Variant #1: obfuscation target: `browser`', () => {
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
sourceMapFileName: 'foo',
target: ObfuscationTarget.Browser
}
).getObfuscatedCode();
});
it('should pass validation when obfuscation target is `browser`', () => {
assert.doesNotThrow(testFunc);
});
});
describe('Variant #2: obfuscation target: `node` and default value', () => {
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
sourceMapFileName: '',
target: ObfuscationTarget.Node
}
).getObfuscatedCode();
});
it('should pass validation when obfuscation target is `node` and value is default', () => {
assert.doesNotThrow(testFunc);
});
});
});
describe('Variant #2: negative validation', () => {
const expectedError: string = 'This option allowed only for obfuscation targets';
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
sourceMapFileName: 'foo',
target: ObfuscationTarget.Node
}
).getObfuscatedCode();
});
it('should not pass validation when obfuscation target is `node` and value is not default', () => {
assert.throws(testFunc, expectedError);
});
});
});
@@ -0,0 +1,71 @@
import { assert } from 'chai';
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
import { ObfuscationTarget } from '../../../../../src/enums/ObfuscationTarget';
import { SourceMapMode } from '../../../../../src/enums/source-map/SourceMapMode';
describe('`sourceMapMode` IsAllowedForObfuscationTarget validator', () => {
describe('Variant #1: positive validation', () => {
describe('Variant #1: obfuscation target: `browser`', () => {
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
sourceMapMode: SourceMapMode.Inline,
target: ObfuscationTarget.Browser
}
).getObfuscatedCode();
});
it('should pass validation when obfuscation target is `browser`', () => {
assert.doesNotThrow(testFunc);
});
});
describe('Variant #2: obfuscation target: `node` and default value', () => {
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
sourceMapMode: SourceMapMode.Separate,
target: ObfuscationTarget.Node
}
).getObfuscatedCode();
});
it('should pass validation when obfuscation target is `node` and value is default', () => {
assert.doesNotThrow(testFunc);
});
});
});
describe('Variant #2: negative validation', () => {
const expectedError: string = 'This option allowed only for obfuscation targets';
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
sourceMapMode: SourceMapMode.Inline,
target: ObfuscationTarget.Node
}
).getObfuscatedCode();
});
it('should not pass validation when obfuscation target is `node` and value is not default', () => {
assert.throws(testFunc, expectedError);
});
});
});
@@ -0,0 +1,70 @@
import { assert } from 'chai';
import { JavaScriptObfuscator } from '../../../../../src/JavaScriptObfuscatorFacade';
import { NO_ADDITIONAL_NODES_PRESET } from '../../../../../src/options/presets/NoCustomNodes';
import { ObfuscationTarget } from '../../../../../src/enums/ObfuscationTarget';
describe('`sourceMap` IsAllowedForObfuscationTarget validator', () => {
describe('Variant #1: positive validation', () => {
describe('Variant #1: obfuscation target: `browser`', () => {
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
sourceMap: true,
target: ObfuscationTarget.Browser
}
).getObfuscatedCode();
});
it('should pass validation when obfuscation target is `browser`', () => {
assert.doesNotThrow(testFunc);
});
});
describe('Variant #2: obfuscation target: `node` and default value', () => {
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
sourceMap: false,
target: ObfuscationTarget.Node
}
).getObfuscatedCode();
});
it('should pass validation when obfuscation target is `node` and value is default', () => {
assert.doesNotThrow(testFunc);
});
});
});
describe('Variant #2: negative validation', () => {
const expectedError: string = 'This option allowed only for obfuscation targets';
let testFunc: () => string;
beforeEach(() => {
testFunc = () => JavaScriptObfuscator.obfuscate(
'',
{
...NO_ADDITIONAL_NODES_PRESET,
sourceMap: true,
target: ObfuscationTarget.Node
}
).getObfuscatedCode();
});
it('should not pass validation when obfuscation target is `node` and value is not default', () => {
assert.throws(testFunc, expectedError);
});
});
});
+5
View File
@@ -89,6 +89,11 @@ import './functional-tests/node-transformers/preparing-transformers/obfuscating-
import './functional-tests/node-transformers/preparing-transformers/obfuscating-guards/conditional-comment-obfuscating-guard/ConditionalCommentObfuscatingGuard.spec';
import './functional-tests/node-transformers/preparing-transformers/obfuscating-guards/reserved-string-obfuscating-guard/ReservedStringObfuscatingGuard.spec';
import './functional-tests/options/OptionsNormalizer.spec';
import './functional-tests/options/domain-lock/validators/IsAllowedForObfuscationTarget.spec';
import './functional-tests/options/source-map/validators/IsAllowedForObfuscationTarget.spec';
import './functional-tests/options/source-map-base-url/validators/IsAllowedForObfuscationTarget.spec';
import './functional-tests/options/source-map-file-name/validators/IsAllowedForObfuscationTarget.spec';
import './functional-tests/options/source-map-mode/validators/IsAllowedForObfuscationTarget.spec';
import './functional-tests/storages/string-array-storage/StringArrayStorage.spec';
import './functional-tests/templates/debug-protection-nodes/DebugProtectionFunctionCallTemplate.spec';
import './functional-tests/templates/domain-lock-nodes/DomainLockNodeTemplate.spec';
+5
View File
@@ -1770,6 +1770,11 @@ fast-deep-equal@^2.0.1:
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
fast-deep-equal@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4"
integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==
fast-json-stable-stringify@^2.0.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz#874bf69c6f404c2b5d99c481341399fd55892633"