@adobe-commerce/aio-toolkit 1.0.17 → 1.0.18

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
@@ -5,6 +5,66 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.0.18] - 2026-03-03
9
+
10
+ ### 🔒 Security Fixes
11
+
12
+ - **CRITICAL: Removed vulnerable @modelcontextprotocol/sdk transitive dependency**
13
+ - Removed `@adobe-commerce/commerce-extensibility-tools` from peer dependencies
14
+ - Eliminates unfixable security vulnerabilities (CVE: ReDoS, DNS rebinding)
15
+ - Addresses user-reported security concerns from npm audit
16
+ - MCP Server integration feature now requires manual installation
17
+ - Package contained two HIGH severity vulnerabilities:
18
+ - **ReDoS vulnerability** (GHSA-8r9q-7v3j-jr4g): Malicious regex input can crash the application
19
+ - **DNS rebinding protection disabled by default** (GHSA-w48q-cv73-mx4w): Allows potential security bypass attacks
20
+
21
+ - **Updated vulnerable devDependencies**
22
+ - `ajv`: 6.12.6 → 6.14.0, 8.17.1 → 8.18.0 (ReDoS fixes - moderate severity)
23
+ - `fast-xml-parser`: 5.3.5 → 5.4.2 (DoS/stack overflow fixes - high severity)
24
+ - `minimatch`: multiple versions updated to latest patch releases (ReDoS fixes - high severity)
25
+ - `rollup`: 4.57.1 → 4.59.0 (path traversal fix - high severity)
26
+ - Total vulnerabilities reduced from 11 to 6 (10 fixed, 1 made optional)
27
+ - Remaining 6 vulnerabilities are in devDependencies only (TypeScript ESLint tooling)
28
+
29
+ ### ⚠️ Breaking Changes
30
+
31
+ - **Cursor IDE MCP Server Integration (`aio-toolkit-cursor-context`)**
32
+ - `@adobe-commerce/commerce-extensibility-tools` is no longer a peer dependency
33
+ - Users who want MCP integration must manually install the optional package:
34
+ ```bash
35
+ npm install @adobe-commerce/commerce-extensibility-tools
36
+ ```
37
+ - **Security Warning**: This package contains known vulnerabilities in `@modelcontextprotocol/sdk@0.4.0`
38
+ - CLI gracefully handles missing package with clear installation instructions
39
+ - All other toolkit features work normally without this optional dependency
40
+
41
+ ### 📝 Technical Details
42
+
43
+ - Updated `package.json` to remove peer dependency on `@adobe-commerce/commerce-extensibility-tools`
44
+ - Added security documentation to README with clear warnings about MCP feature
45
+ - MCP config helper (`McpConfig` class) already handles missing package gracefully
46
+ - No changes required to existing code - backward compatible for 90%+ of users
47
+ - Applied automated security patches via `npm audit fix`
48
+
49
+ ### 💡 Migration Guide
50
+
51
+ **For users NOT using Cursor IDE MCP feature:**
52
+ ```bash
53
+ # No action required - update normally
54
+ npm install @adobe-commerce/aio-toolkit@1.0.18
55
+ ```
56
+
57
+ **For users using Cursor IDE MCP feature:**
58
+ ```bash
59
+ # Update toolkit and install optional dependency
60
+ npm install @adobe-commerce/aio-toolkit@1.0.18
61
+ npm install @adobe-commerce/commerce-extensibility-tools
62
+ ```
63
+
64
+ **Alternative:** Wait for upstream fix from Adobe to release a patched version of `commerce-extensibility-tools` that uses a secure `@modelcontextprotocol/sdk` version (≥1.25.2).
65
+
66
+ ---
67
+
8
68
  ## [1.0.17] - 2026-02-25
9
69
 
10
70
  ### ✨ Features
package/README.md CHANGED
@@ -1495,6 +1495,23 @@ await manager.delete('your-registration-id');
1495
1495
 
1496
1496
  Command-line tool for managing Cursor IDE context files (rules and commands) in your Adobe App Builder projects. This CLI automatically sets up Cursor IDE-specific contexts and configures the Model Context Protocol (MCP) server for enhanced development experience.
1497
1497
 
1498
+ > **⚠️ Security Notice - MCP Server Integration**
1499
+ >
1500
+ > The MCP (Model Context Protocol) server feature requires the optional package `@adobe-commerce/commerce-extensibility-tools`. This package is **not installed by default** due to known security vulnerabilities in its dependencies.
1501
+ >
1502
+ > **If you want to use MCP integration:**
1503
+ > ```bash
1504
+ > npm install @adobe-commerce/commerce-extensibility-tools
1505
+ > ```
1506
+ >
1507
+ > **Known Vulnerabilities:**
1508
+ > - ReDoS (Regular Expression Denial of Service) vulnerability in `@modelcontextprotocol/sdk`
1509
+ > - DNS rebinding protection disabled by default in `@modelcontextprotocol/sdk`
1510
+ >
1511
+ > **Recommendation:** Only install this package if you specifically need MCP server integration for Cursor IDE. Monitor the [package repository](https://www.npmjs.com/package/@adobe-commerce/commerce-extensibility-tools) for security updates.
1512
+ >
1513
+ > All other toolkit features work normally without this optional dependency.
1514
+
1498
1515
  ##### Commands
1499
1516
 
1500
1517
  ###### `check`
@@ -12021,385 +12021,12 @@ var init_onboard_events = __esm({
12021
12021
  }
12022
12022
  });
12023
12023
 
12024
- // node_modules/dotenv/package.json
12025
- var require_package = __commonJS({
12026
- "node_modules/dotenv/package.json"(exports2, module2) {
12027
- module2.exports = {
12028
- name: "dotenv",
12029
- version: "16.6.1",
12030
- description: "Loads environment variables from .env file",
12031
- main: "lib/main.js",
12032
- types: "lib/main.d.ts",
12033
- exports: {
12034
- ".": {
12035
- types: "./lib/main.d.ts",
12036
- require: "./lib/main.js",
12037
- default: "./lib/main.js"
12038
- },
12039
- "./config": "./config.js",
12040
- "./config.js": "./config.js",
12041
- "./lib/env-options": "./lib/env-options.js",
12042
- "./lib/env-options.js": "./lib/env-options.js",
12043
- "./lib/cli-options": "./lib/cli-options.js",
12044
- "./lib/cli-options.js": "./lib/cli-options.js",
12045
- "./package.json": "./package.json"
12046
- },
12047
- scripts: {
12048
- "dts-check": "tsc --project tests/types/tsconfig.json",
12049
- lint: "standard",
12050
- pretest: "npm run lint && npm run dts-check",
12051
- test: "tap run --allow-empty-coverage --disable-coverage --timeout=60000",
12052
- "test:coverage": "tap run --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov",
12053
- prerelease: "npm test",
12054
- release: "standard-version"
12055
- },
12056
- repository: {
12057
- type: "git",
12058
- url: "git://github.com/motdotla/dotenv.git"
12059
- },
12060
- homepage: "https://github.com/motdotla/dotenv#readme",
12061
- funding: "https://dotenvx.com",
12062
- keywords: [
12063
- "dotenv",
12064
- "env",
12065
- ".env",
12066
- "environment",
12067
- "variables",
12068
- "config",
12069
- "settings"
12070
- ],
12071
- readmeFilename: "README.md",
12072
- license: "BSD-2-Clause",
12073
- devDependencies: {
12074
- "@types/node": "^18.11.3",
12075
- decache: "^4.6.2",
12076
- sinon: "^14.0.1",
12077
- standard: "^17.0.0",
12078
- "standard-version": "^9.5.0",
12079
- tap: "^19.2.0",
12080
- typescript: "^4.8.4"
12081
- },
12082
- engines: {
12083
- node: ">=12"
12084
- },
12085
- browser: {
12086
- fs: false
12087
- }
12088
- };
12089
- }
12090
- });
12091
-
12092
- // node_modules/dotenv/lib/main.js
12093
- var require_main = __commonJS({
12094
- "node_modules/dotenv/lib/main.js"(exports2, module2) {
12095
- "use strict";
12096
- var fs2 = require("fs");
12097
- var path2 = require("path");
12098
- var os = require("os");
12099
- var crypto2 = require("crypto");
12100
- var packageJson = require_package();
12101
- var version = packageJson.version;
12102
- var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
12103
- function parse2(src) {
12104
- const obj = {};
12105
- let lines = src.toString();
12106
- lines = lines.replace(/\r\n?/mg, "\n");
12107
- let match;
12108
- while ((match = LINE.exec(lines)) != null) {
12109
- const key = match[1];
12110
- let value = match[2] || "";
12111
- value = value.trim();
12112
- const maybeQuote = value[0];
12113
- value = value.replace(/^(['"`])([\s\S]*)\1$/mg, "$2");
12114
- if (maybeQuote === '"') {
12115
- value = value.replace(/\\n/g, "\n");
12116
- value = value.replace(/\\r/g, "\r");
12117
- }
12118
- obj[key] = value;
12119
- }
12120
- return obj;
12121
- }
12122
- __name(parse2, "parse");
12123
- function _parseVault(options) {
12124
- options = options || {};
12125
- const vaultPath = _vaultPath(options);
12126
- options.path = vaultPath;
12127
- const result = DotenvModule.configDotenv(options);
12128
- if (!result.parsed) {
12129
- const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
12130
- err.code = "MISSING_DATA";
12131
- throw err;
12132
- }
12133
- const keys = _dotenvKey(options).split(",");
12134
- const length = keys.length;
12135
- let decrypted;
12136
- for (let i = 0; i < length; i++) {
12137
- try {
12138
- const key = keys[i].trim();
12139
- const attrs = _instructions(result, key);
12140
- decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
12141
- break;
12142
- } catch (error) {
12143
- if (i + 1 >= length) {
12144
- throw error;
12145
- }
12146
- }
12147
- }
12148
- return DotenvModule.parse(decrypted);
12149
- }
12150
- __name(_parseVault, "_parseVault");
12151
- function _warn(message) {
12152
- console.log(`[dotenv@${version}][WARN] ${message}`);
12153
- }
12154
- __name(_warn, "_warn");
12155
- function _debug(message) {
12156
- console.log(`[dotenv@${version}][DEBUG] ${message}`);
12157
- }
12158
- __name(_debug, "_debug");
12159
- function _log(message) {
12160
- console.log(`[dotenv@${version}] ${message}`);
12161
- }
12162
- __name(_log, "_log");
12163
- function _dotenvKey(options) {
12164
- if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {
12165
- return options.DOTENV_KEY;
12166
- }
12167
- if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {
12168
- return process.env.DOTENV_KEY;
12169
- }
12170
- return "";
12171
- }
12172
- __name(_dotenvKey, "_dotenvKey");
12173
- function _instructions(result, dotenvKey) {
12174
- let uri;
12175
- try {
12176
- uri = new URL(dotenvKey);
12177
- } catch (error) {
12178
- if (error.code === "ERR_INVALID_URL") {
12179
- const err = new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");
12180
- err.code = "INVALID_DOTENV_KEY";
12181
- throw err;
12182
- }
12183
- throw error;
12184
- }
12185
- const key = uri.password;
12186
- if (!key) {
12187
- const err = new Error("INVALID_DOTENV_KEY: Missing key part");
12188
- err.code = "INVALID_DOTENV_KEY";
12189
- throw err;
12190
- }
12191
- const environment = uri.searchParams.get("environment");
12192
- if (!environment) {
12193
- const err = new Error("INVALID_DOTENV_KEY: Missing environment part");
12194
- err.code = "INVALID_DOTENV_KEY";
12195
- throw err;
12196
- }
12197
- const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
12198
- const ciphertext = result.parsed[environmentKey];
12199
- if (!ciphertext) {
12200
- const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
12201
- err.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
12202
- throw err;
12203
- }
12204
- return { ciphertext, key };
12205
- }
12206
- __name(_instructions, "_instructions");
12207
- function _vaultPath(options) {
12208
- let possibleVaultPath = null;
12209
- if (options && options.path && options.path.length > 0) {
12210
- if (Array.isArray(options.path)) {
12211
- for (const filepath of options.path) {
12212
- if (fs2.existsSync(filepath)) {
12213
- possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
12214
- }
12215
- }
12216
- } else {
12217
- possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
12218
- }
12219
- } else {
12220
- possibleVaultPath = path2.resolve(process.cwd(), ".env.vault");
12221
- }
12222
- if (fs2.existsSync(possibleVaultPath)) {
12223
- return possibleVaultPath;
12224
- }
12225
- return null;
12226
- }
12227
- __name(_vaultPath, "_vaultPath");
12228
- function _resolveHome(envPath) {
12229
- return envPath[0] === "~" ? path2.join(os.homedir(), envPath.slice(1)) : envPath;
12230
- }
12231
- __name(_resolveHome, "_resolveHome");
12232
- function _configVault(options) {
12233
- const debug = Boolean(options && options.debug);
12234
- const quiet = options && "quiet" in options ? options.quiet : true;
12235
- if (debug || !quiet) {
12236
- _log("Loading env from encrypted .env.vault");
12237
- }
12238
- const parsed = DotenvModule._parseVault(options);
12239
- let processEnv = process.env;
12240
- if (options && options.processEnv != null) {
12241
- processEnv = options.processEnv;
12242
- }
12243
- DotenvModule.populate(processEnv, parsed, options);
12244
- return { parsed };
12245
- }
12246
- __name(_configVault, "_configVault");
12247
- function configDotenv(options) {
12248
- const dotenvPath = path2.resolve(process.cwd(), ".env");
12249
- let encoding = "utf8";
12250
- const debug = Boolean(options && options.debug);
12251
- const quiet = options && "quiet" in options ? options.quiet : true;
12252
- if (options && options.encoding) {
12253
- encoding = options.encoding;
12254
- } else {
12255
- if (debug) {
12256
- _debug("No encoding is specified. UTF-8 is used by default");
12257
- }
12258
- }
12259
- let optionPaths = [dotenvPath];
12260
- if (options && options.path) {
12261
- if (!Array.isArray(options.path)) {
12262
- optionPaths = [_resolveHome(options.path)];
12263
- } else {
12264
- optionPaths = [];
12265
- for (const filepath of options.path) {
12266
- optionPaths.push(_resolveHome(filepath));
12267
- }
12268
- }
12269
- }
12270
- let lastError;
12271
- const parsedAll = {};
12272
- for (const path3 of optionPaths) {
12273
- try {
12274
- const parsed = DotenvModule.parse(fs2.readFileSync(path3, { encoding }));
12275
- DotenvModule.populate(parsedAll, parsed, options);
12276
- } catch (e) {
12277
- if (debug) {
12278
- _debug(`Failed to load ${path3} ${e.message}`);
12279
- }
12280
- lastError = e;
12281
- }
12282
- }
12283
- let processEnv = process.env;
12284
- if (options && options.processEnv != null) {
12285
- processEnv = options.processEnv;
12286
- }
12287
- DotenvModule.populate(processEnv, parsedAll, options);
12288
- if (debug || !quiet) {
12289
- const keysCount = Object.keys(parsedAll).length;
12290
- const shortPaths = [];
12291
- for (const filePath of optionPaths) {
12292
- try {
12293
- const relative = path2.relative(process.cwd(), filePath);
12294
- shortPaths.push(relative);
12295
- } catch (e) {
12296
- if (debug) {
12297
- _debug(`Failed to load ${filePath} ${e.message}`);
12298
- }
12299
- lastError = e;
12300
- }
12301
- }
12302
- _log(`injecting env (${keysCount}) from ${shortPaths.join(",")}`);
12303
- }
12304
- if (lastError) {
12305
- return { parsed: parsedAll, error: lastError };
12306
- } else {
12307
- return { parsed: parsedAll };
12308
- }
12309
- }
12310
- __name(configDotenv, "configDotenv");
12311
- function config5(options) {
12312
- if (_dotenvKey(options).length === 0) {
12313
- return DotenvModule.configDotenv(options);
12314
- }
12315
- const vaultPath = _vaultPath(options);
12316
- if (!vaultPath) {
12317
- _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`);
12318
- return DotenvModule.configDotenv(options);
12319
- }
12320
- return DotenvModule._configVault(options);
12321
- }
12322
- __name(config5, "config");
12323
- function decrypt(encrypted, keyStr) {
12324
- const key = Buffer.from(keyStr.slice(-64), "hex");
12325
- let ciphertext = Buffer.from(encrypted, "base64");
12326
- const nonce = ciphertext.subarray(0, 12);
12327
- const authTag = ciphertext.subarray(-16);
12328
- ciphertext = ciphertext.subarray(12, -16);
12329
- try {
12330
- const aesgcm = crypto2.createDecipheriv("aes-256-gcm", key, nonce);
12331
- aesgcm.setAuthTag(authTag);
12332
- return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
12333
- } catch (error) {
12334
- const isRange = error instanceof RangeError;
12335
- const invalidKeyLength = error.message === "Invalid key length";
12336
- const decryptionFailed = error.message === "Unsupported state or unable to authenticate data";
12337
- if (isRange || invalidKeyLength) {
12338
- const err = new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
12339
- err.code = "INVALID_DOTENV_KEY";
12340
- throw err;
12341
- } else if (decryptionFailed) {
12342
- const err = new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
12343
- err.code = "DECRYPTION_FAILED";
12344
- throw err;
12345
- } else {
12346
- throw error;
12347
- }
12348
- }
12349
- }
12350
- __name(decrypt, "decrypt");
12351
- function populate(processEnv, parsed, options = {}) {
12352
- const debug = Boolean(options && options.debug);
12353
- const override = Boolean(options && options.override);
12354
- if (typeof parsed !== "object") {
12355
- const err = new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
12356
- err.code = "OBJECT_REQUIRED";
12357
- throw err;
12358
- }
12359
- for (const key of Object.keys(parsed)) {
12360
- if (Object.prototype.hasOwnProperty.call(processEnv, key)) {
12361
- if (override === true) {
12362
- processEnv[key] = parsed[key];
12363
- }
12364
- if (debug) {
12365
- if (override === true) {
12366
- _debug(`"${key}" is already defined and WAS overwritten`);
12367
- } else {
12368
- _debug(`"${key}" is already defined and was NOT overwritten`);
12369
- }
12370
- }
12371
- } else {
12372
- processEnv[key] = parsed[key];
12373
- }
12374
- }
12375
- }
12376
- __name(populate, "populate");
12377
- var DotenvModule = {
12378
- configDotenv,
12379
- _configVault,
12380
- _parseVault,
12381
- config: config5,
12382
- decrypt,
12383
- parse: parse2,
12384
- populate
12385
- };
12386
- module2.exports.configDotenv = DotenvModule.configDotenv;
12387
- module2.exports._configVault = DotenvModule._configVault;
12388
- module2.exports._parseVault = DotenvModule._parseVault;
12389
- module2.exports.config = DotenvModule.config;
12390
- module2.exports.decrypt = DotenvModule.decrypt;
12391
- module2.exports.parse = DotenvModule.parse;
12392
- module2.exports.populate = DotenvModule.populate;
12393
- module2.exports = DotenvModule;
12394
- }
12395
- });
12396
-
12397
12024
  // src/commands/framework/helpers/io-environment/index.ts
12398
12025
  var dotenv, _IOEnvironmentLoader, IOEnvironmentLoader;
12399
12026
  var init_io_environment = __esm({
12400
12027
  "src/commands/framework/helpers/io-environment/index.ts"() {
12401
12028
  "use strict";
12402
- dotenv = __toESM(require_main());
12029
+ dotenv = __toESM(require("dotenv"));
12403
12030
  dotenv.config();
12404
12031
  _IOEnvironmentLoader = class _IOEnvironmentLoader {
12405
12032
  /**
@@ -12717,7 +12344,7 @@ var init_io_events2 = __esm({
12717
12344
  init_onboard_events();
12718
12345
  init_io_environment();
12719
12346
  init_adobe_auth_token();
12720
- dotenv2 = __toESM(require_main());
12347
+ dotenv2 = __toESM(require("dotenv"));
12721
12348
  dotenv2.config();
12722
12349
  _ExecuteIOEvents = class _ExecuteIOEvents {
12723
12350
  constructor(applicationName, ioEventsConfig) {
@@ -13912,7 +13539,7 @@ var init_commerce2 = __esm({
13912
13539
  init_onboard_commerce();
13913
13540
  init_commerce_environment();
13914
13541
  init_adobe_commerce_client2();
13915
- dotenv3 = __toESM(require_main());
13542
+ dotenv3 = __toESM(require("dotenv"));
13916
13543
  dotenv3.config();
13917
13544
  _ExecuteCommerce = class _ExecuteCommerce {
13918
13545
  constructor(commerceAuthType, commerceProvider, commerceEventsConfig, isPaaSInstance, logger) {
@@ -14088,7 +13715,7 @@ var init_io_events3 = __esm({
14088
13715
  init_registration();
14089
13716
  init_io_environment();
14090
13717
  init_adobe_auth_token();
14091
- dotenv4 = __toESM(require_main());
13718
+ dotenv4 = __toESM(require("dotenv"));
14092
13719
  dotenv4.config();
14093
13720
  _CleanupIOEvents = class _CleanupIOEvents {
14094
13721
  /**