jscrambler 8.10.9 → 8.11.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # jscrambler
2
2
 
3
+ ## 8.11.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [e473dc2]: Fix axios vulnerability
8
+
9
+ ## 8.11.0
10
+
11
+ ### Minor Changes
12
+
13
+ - [63d90aa]: Add support for custom labels in protection requests
14
+
3
15
  ## 8.10.9
4
16
 
5
17
  ### Patch Changes
package/README.md CHANGED
@@ -26,6 +26,7 @@ If you're looking to gain control over third-party tags and achieve PCI DSS comp
26
26
  - [Instrument (`--instrument`)](#instrument---instrument)
27
27
  - [Symbol Table](#symbol-table)
28
28
  - [Global Names Prefix](#global-names-prefix)
29
+ - [Custom labels (customLabels)](#custom-labels-customlabels)
29
30
  - [API](#api)
30
31
  - [Quick example](#quick-example)
31
32
  - [Jscrambler Parameters](#jscrambler-parameters)
@@ -146,6 +147,7 @@ Options:
146
147
  --protection-report <string> (version 8.4 and above) Protection id for the metadata report
147
148
  --use-global-names-on-modules <bool> (version 8.5 and above) Force the usage of more complex names on modules (default: false)
148
149
  --generate-alias <bool> Generate alias for the transformations (default: true)
150
+ --custom-label <key=value> Attach a custom label to the protection (repeatable)
149
151
  -h, --help output usage information
150
152
  ```
151
153
 
@@ -441,6 +443,33 @@ If you apply the previous configuration, all generated global variable names wil
441
443
 
442
444
  ***Note***: The `globalNamesPrefix` parameter must be **short** and **unintelligible** to avoid code size increase and automated attacks
443
445
 
446
+ ## Custom labels (customLabels)
447
+
448
+ You can attach optional **custom labels** to a protection request: a plain object of string keys and string values. They are sent to the API as **`customLabels`** (for example to record build environment, version, or CI metadata). Your Jscrambler API version must support this field; on older APIs the client may omit it and print a warning.
449
+
450
+ ### Configuration file
451
+
452
+ Add a `customLabels` object next to your other options (for example in `.jscramblerrc` or a file passed with `-c, --config`):
453
+
454
+ ```json
455
+ {
456
+ "customLabels": {
457
+ "env": "production",
458
+ "version": "9.2.2"
459
+ }
460
+ }
461
+ ```
462
+
463
+ Keys must be non-empty strings; values must be strings (use quoted JSON for numeric-looking values, e.g. `"9.2.2"`).
464
+
465
+ ### CLI
466
+
467
+ Use **`--custom-label`** with `key=value`. You can pass it multiple times. Only the first `=` splits the key from the value (so values may contain `=`). If the same key appears in the config file and on the command line, the **CLI value wins**.
468
+
469
+ ```bash
470
+ jscrambler -c config.json --custom-label env=production --custom-label version=9.2.2 -o out/ "src/**/*.js"
471
+ ```
472
+
444
473
  ## API
445
474
  ```bash
446
475
  npm install jscrambler
@@ -106,7 +106,20 @@ const validateBeforeProtection = function () {
106
106
  });
107
107
  return beforeProtectionArray;
108
108
  };
109
- _commander.default.version(require('../../package.json').version).usage('[options] <file ...>').option('-a, --access-key <accessKey>', 'Access key').option('-c, --config <config>', 'Jscrambler configuration options').option('-H, --host <host>', 'Hostname').option('-i, --application-id <id>', 'Application ID').option('-o, --output-dir <dir>', 'Output directory').option('-p, --port <port>', 'Port').option('--base-path <path>', 'Base Path').option('--protocol <protocol>', 'Protocol (http or https)').option('--cafile <path>', 'Internal certificate authority').option('-C, --cwd <dir>', 'Current Working Directory').option('-s, --secret-key <secretKey>', 'Secret key').option('-m, --source-maps <id>', 'Download source maps').option('-R, --randomization-seed <seed>', 'Set randomization seed').option('--instrument', 'Instrument file(s) before start profiling. ATTENTION: previous profiling information will be deleted').option('--start-profiling', 'Starts profiling (assumes an already instrumented application)').option('--stop-profiling', 'Stops profiling').option('--code-hardening-threshold <threshold>', 'Set code hardening file size threshold. Format: {value}{unit="b,kb,mb"}. Example: 200kb', validateCodeHardeningThreshold).option('--recommended-order <bool>', 'Use recommended order', validateBool('recommended-order')).option('-W, --werror <bool>', 'Set werror flag value (default: true)', validateBool('werror')).option('--utc <bool>', 'Set UTC as the request time zone. Otherwise it uses the local time zone (default: true)', validateBool('utc')).option('--tolerate-minification <bool>', "Don't detect minification as malicious tampering (default: true)", validateBool('tolerate-minification')).option('--use-profiling-data <bool>', "(version 6.2 only) Protection should use the existing profiling data (default: true)", validateBool('use-profiling-data')).option('--profiling-data-mode <mode>', "(version 6.3 and above) Select profiling mode (default: automatic)", validateProfilingDataMode).option('--remove-profiling-data', "Removes the current application profiling information").option('--use-app-classification <bool>', '(version 6.3 and above) Protection should use Application Classification metadata when protecting (default: true)', validateBool('--use-app-classification')).option('--input-symbol-table <file>', '(version 6.3 and above) Protection should use symbol table when protecting. (default: no file)').option('--output-symbol-table <id>', '(version 6.3 and above) Download output symbol table (json)').option('--jscramblerVersion <version>', 'Use a specific Jscrambler version').option('--debugMode', 'Protect in debug mode').option('--skip-sources', 'Prevent source files from being updated').option('--force-app-environment <environment>', "(version 7.1 and above) Override application's environment detected automatically. Possible values: ".concat(availableEnvironments.toString()), validateForceAppEnvironment).option('--ensure-code-annotation <bool>', "(version 7.3 and above) Fail protection if no annotations are found on the source code (default: false)", validateBool('ensure-code-annotation')).option('-n <number>', "(version 7.2 and above) Create multiple protections at once.").option('--delete-protection-on-success <bool>', 'Deletes the protection files after they have been protected and downloaded (default: false)', validateBool('--delete-protection-on-success')).option('--mode <mode>', "(version 8.4 and above) Define protection mode. Possible values: automatic, manual (default: manual)", validateMode).option('--save-src <bool>', 'Protection should save application sources (default: true)', validateBool('--save-src')).option('--protection-report <string>', '(version 8.4 and above) Protection id for the metadata report').option('--use-global-names-on-modules <bool>', '(version 8.5 and above) Force the usage of more complex names on modules').option('--balance', '(version 8.4 and above) Gets the balance of the user').option('--generate-alias <bool>', '(version 8.5 and above) Generate alias for the transformations (default: true)', validateBool('--generate-alias')).parse(process.argv);
109
+ const parseCustomLabelCommandLineOption = function (val) {
110
+ let accumulator = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
111
+ const idx = val.indexOf('=');
112
+ if (idx < 1) {
113
+ console.error("*--custom-label* expects key=value (for example --custom-label \"env=production\"), got \"".concat(val, "\""));
114
+ process.exit(1);
115
+ }
116
+ const key = val.slice(0, idx);
117
+ const value = val.slice(idx + 1);
118
+ return _objectSpread(_objectSpread({}, accumulator), {}, {
119
+ [key]: value
120
+ });
121
+ };
122
+ _commander.default.version(require('../../package.json').version).usage('[options] <file ...>').option('-a, --access-key <accessKey>', 'Access key').option('-c, --config <config>', 'Jscrambler configuration options').option('-H, --host <host>', 'Hostname').option('-i, --application-id <id>', 'Application ID').option('-o, --output-dir <dir>', 'Output directory').option('-p, --port <port>', 'Port').option('--base-path <path>', 'Base Path').option('--protocol <protocol>', 'Protocol (http or https)').option('--cafile <path>', 'Internal certificate authority').option('-C, --cwd <dir>', 'Current Working Directory').option('-s, --secret-key <secretKey>', 'Secret key').option('-m, --source-maps <id>', 'Download source maps').option('-R, --randomization-seed <seed>', 'Set randomization seed').option('--instrument', 'Instrument file(s) before start profiling. ATTENTION: previous profiling information will be deleted').option('--start-profiling', 'Starts profiling (assumes an already instrumented application)').option('--stop-profiling', 'Stops profiling').option('--code-hardening-threshold <threshold>', 'Set code hardening file size threshold. Format: {value}{unit="b,kb,mb"}. Example: 200kb', validateCodeHardeningThreshold).option('--recommended-order <bool>', 'Use recommended order', validateBool('recommended-order')).option('-W, --werror <bool>', 'Set werror flag value (default: true)', validateBool('werror')).option('--utc <bool>', 'Set UTC as the request time zone. Otherwise it uses the local time zone (default: true)', validateBool('utc')).option('--tolerate-minification <bool>', "Don't detect minification as malicious tampering (default: true)", validateBool('tolerate-minification')).option('--use-profiling-data <bool>', "(version 6.2 only) Protection should use the existing profiling data (default: true)", validateBool('use-profiling-data')).option('--profiling-data-mode <mode>', "(version 6.3 and above) Select profiling mode (default: automatic)", validateProfilingDataMode).option('--remove-profiling-data', "Removes the current application profiling information").option('--use-app-classification <bool>', '(version 6.3 and above) Protection should use Application Classification metadata when protecting (default: true)', validateBool('--use-app-classification')).option('--input-symbol-table <file>', '(version 6.3 and above) Protection should use symbol table when protecting. (default: no file)').option('--output-symbol-table <id>', '(version 6.3 and above) Download output symbol table (json)').option('--jscramblerVersion <version>', 'Use a specific Jscrambler version').option('--debugMode', 'Protect in debug mode').option('--skip-sources', 'Prevent source files from being updated').option('--force-app-environment <environment>', "(version 7.1 and above) Override application's environment detected automatically. Possible values: ".concat(availableEnvironments.toString()), validateForceAppEnvironment).option('--ensure-code-annotation <bool>', "(version 7.3 and above) Fail protection if no annotations are found on the source code (default: false)", validateBool('ensure-code-annotation')).option('-n <number>', "(version 7.2 and above) Create multiple protections at once.").option('--delete-protection-on-success <bool>', 'Deletes the protection files after they have been protected and downloaded (default: false)', validateBool('--delete-protection-on-success')).option('--mode <mode>', "(version 8.4 and above) Define protection mode. Possible values: automatic, manual (default: manual)", validateMode).option('--save-src <bool>', 'Protection should save application sources (default: true)', validateBool('--save-src')).option('--protection-report <string>', '(version 8.4 and above) Protection id for the metadata report').option('--use-global-names-on-modules <bool>', '(version 8.5 and above) Force the usage of more complex names on modules').option('--balance', '(version 8.4 and above) Gets the balance of the user').option('--generate-alias <bool>', '(version 8.5 and above) Generate alias for the transformations', validateBool('--generate-alias')).option('--custom-label <key=value>', 'Attach a custom label to the protection (repeatable). Example: --custom-label "env=production"', parseCustomLabelCommandLineOption, {}).parse(process.argv);
110
123
  let globSrc, filesSrc, config;
111
124
 
112
125
  // If -c, --config file was provided
@@ -117,6 +130,9 @@ if (_commander.default.config) {
117
130
  } else {
118
131
  config = {};
119
132
  }
133
+
134
+ // Merge explicit config file (specified by CLI flag `--config`) with `.jscramblerrc` (`_config` fills undefined keys)
135
+ config = (0, _lodash.default)(config, _config2.default);
120
136
  config.accessKey = _commander.default.accessKey || (config.keys ? config.keys.accessKey : undefined);
121
137
  config.secretKey = _commander.default.secretKey || (config.keys ? config.keys.secretKey : undefined);
122
138
  config.host = _commander.default.host || config.host;
@@ -174,7 +190,19 @@ if (_commander.default.forceAppEnvironment) {
174
190
  } else {
175
191
  config.forceAppEnvironment = config.forceAppEnvironment ? validateForceAppEnvironment(config.forceAppEnvironment) : undefined;
176
192
  }
177
- config = (0, _lodash.default)(config, _config2.default);
193
+
194
+ // Validate customLabels from file config
195
+ try {
196
+ config.customLabels = (0, _utils.validateCustomLabels)(config.customLabels);
197
+ } catch (err) {
198
+ console.error(err.message);
199
+ process.exit(1);
200
+ }
201
+ // Merge file config with CLI `--custom-label` flags (CLI wins on duplicate keys)
202
+ config.customLabels = _objectSpread(_objectSpread({}, config.customLabels), _commander.default.customLabel || {});
203
+ if (Object.keys(config.customLabels).length === 0) {
204
+ delete config.customLabels;
205
+ }
178
206
  config.numberOfProtections = (0, _utils.validateNProtections)(_commander.default.N);
179
207
  if (config.codeHardeningThreshold) {
180
208
  config.codeHardeningThreshold = validateCodeHardeningThreshold(config.codeHardeningThreshold);
@@ -281,7 +309,8 @@ const {
281
309
  saveSrc,
282
310
  globalNamesPrefix,
283
311
  useGlobalNamesOnModules,
284
- generateAlias
312
+ generateAlias,
313
+ customLabels
285
314
  } = config;
286
315
  const params = config.params;
287
316
  const incompatibleOptions = ['sourceMaps', 'instrument', 'startProfiling', 'stopProfiling'];
@@ -425,7 +454,8 @@ if (_commander.default.balance) {
425
454
  saveSrc,
426
455
  globalNamesPrefix,
427
456
  useGlobalNamesOnModules,
428
- generateAlias
457
+ generateAlias,
458
+ customLabels
429
459
  });
430
460
  try {
431
461
  if (typeof werror !== 'undefined') {
@@ -16,9 +16,9 @@ function cleanupInputFields(args, fragments) {
16
16
  if (!hasFieldArg && typeof options[field] !== 'undefined') {
17
17
  options[field] = undefined;
18
18
  cleanedUpFragments = cleanedUpFragments.replace(new RegExp(",?[s|\n]*".concat(field)), '');
19
- console.warn("This API Version does not support the ".concat(field, " argument."));
19
+ console.warn("Warning: This API Version does not support the '".concat(field, "' argument."));
20
20
  }
21
21
  }
22
- ['tolerateMinification', 'useProfilingData', 'useAppClassification', 'inputSymbolTable', 'entryPoint', 'ensureCodeAnnotation', 'generateAlias'].forEach(fieldCleanUp);
22
+ ['tolerateMinification', 'useProfilingData', 'useAppClassification', 'inputSymbolTable', 'entryPoint', 'ensureCodeAnnotation', 'generateAlias', 'customLabels'].forEach(fieldCleanUp);
23
23
  return [options, cleanedUpFragments];
24
24
  }
package/dist/index.js CHANGED
@@ -221,6 +221,7 @@ var _default = exports.default = {
221
221
  // {
222
222
  // "filesSrc": [""],
223
223
  // "params": {},
224
+ // "customLabels": { "env": "production", "version": "9.2.2" },
224
225
  // "cwd": "",
225
226
  // "host": "api.jscrambler.com",
226
227
  // "port": "443",
@@ -233,6 +234,9 @@ var _default = exports.default = {
233
234
  //
234
235
  // `params` if provided will replace all the application transformation parameters.
235
236
  //
237
+ // `customLabels` if provided attaches string key-value metadata to the protection request
238
+ // (API must support this field).
239
+ //
236
240
  // `cwd` allows you to set the current working directory to resolve problems with
237
241
  // relative paths with your `filesSrc` is outside the current working directory.
238
242
  //
@@ -286,7 +290,8 @@ var _default = exports.default = {
286
290
  saveSrc,
287
291
  globalNamesPrefix,
288
292
  useGlobalNamesOnModules,
289
- generateAlias
293
+ generateAlias,
294
+ customLabels
290
295
  } = finalConfig;
291
296
  const {
292
297
  accessKey,
@@ -416,6 +421,10 @@ var _default = exports.default = {
416
421
  useGlobalNamesOnModules,
417
422
  generateAlias
418
423
  });
424
+ const normalizedCustomLabels = (0, _utils.validateCustomLabels)(customLabels);
425
+ if (Object.keys(normalizedCustomLabels).length) {
426
+ protectionOptions.customLabels = normalizedCustomLabels;
427
+ }
419
428
  if (finalConfig.inputSymbolTable) {
420
429
  const inputSymbolTableContents = await _fs.default.promises.readFile(finalConfig.inputSymbolTable, 'utf-8');
421
430
  protectionOptions.inputSymbolTable = inputSymbolTableContents;
package/dist/utils.js CHANGED
@@ -7,8 +7,10 @@ exports.PREPEND_JS_TYPE = exports.APPEND_JS_TYPE = void 0;
7
7
  exports.concatenate = concatenate;
8
8
  exports.getMatchedFiles = getMatchedFiles;
9
9
  exports.isJavascriptFile = isJavascriptFile;
10
+ exports.validateCustomLabels = validateCustomLabels;
10
11
  exports.validateNProtections = validateNProtections;
11
12
  exports.validateThresholdFn = void 0;
13
+ require("core-js/modules/web.dom-collections.iterator.js");
12
14
  var _glob = require("glob");
13
15
  var _fs = _interopRequireDefault(require("fs"));
14
16
  var _path = require("path");
@@ -41,6 +43,33 @@ function validateNProtections(n) {
41
43
  }
42
44
  return nProtections;
43
45
  }
46
+
47
+ /**
48
+ * Validate protection `customLabels`: a plain object with non-empty keys and string values.
49
+ * @param {*} customLabels From config or programmatic options; omit or pass `undefined` for none.
50
+ * @returns {Object.<string, string>} A shallow copy when valid; `{}` when `customLabels` is `undefined`.
51
+ * @throws {Error} If `customLabels` is `null`, an array, a non-object, or has invalid keys/values.
52
+ */
53
+ function validateCustomLabels(customLabels) {
54
+ if (typeof customLabels === 'undefined') {
55
+ return {};
56
+ }
57
+ if (customLabels === null || typeof customLabels !== 'object' || Array.isArray(customLabels)) {
58
+ throw new Error('Invalid *customLabels*: expected a plain object. Eg: { "env": "production", "version": "9.2.2" }');
59
+ }
60
+ const out = {};
61
+ for (const key of Object.keys(customLabels)) {
62
+ if (!key) {
63
+ throw new Error('Invalid *customLabels*: keys must be non-empty strings. Eg: { "env": "production", "version": "9.2.2" }');
64
+ }
65
+ const value = customLabels[key];
66
+ if (typeof value !== 'string') {
67
+ throw new Error("Invalid *customLabels*: value for \"".concat(key, "\" must be a string. Eg: { \"env\": \"production\", \"version\": \"9.2.2\" }"));
68
+ }
69
+ out[key] = value;
70
+ }
71
+ return out;
72
+ }
44
73
  const APPEND_JS_TYPE = exports.APPEND_JS_TYPE = 'append-js';
45
74
  const PREPEND_JS_TYPE = exports.PREPEND_JS_TYPE = 'prepend-js';
46
75
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jscrambler",
3
3
  "description": "Jscrambler Code Integrity API client.",
4
- "version": "8.10.9",
4
+ "version": "8.11.1",
5
5
  "homepage": "https://github.com/jscrambler/jscrambler",
6
6
  "author": "Jscrambler <support@jscrambler.com>",
7
7
  "repository": {
@@ -21,7 +21,7 @@
21
21
  "node": ">= 12.17.0"
22
22
  },
23
23
  "dependencies": {
24
- "axios": "1.13.5",
24
+ "axios": "1.15.0",
25
25
  "commander": "^2.8.1",
26
26
  "core-js": "3.38.1",
27
27
  "filesize-parser": "1.5.0",