mirror of
https://github.com/Alfresco/alfresco-ng2-components.git
synced 2026-09-09 18:03:21 +00:00
AAE-40427 Replace shelljs with native node api (#11404)
* Replace shelljs with native node api * Refactor command execution in audit and changelog scripts to use spawnSync for improved security and error handling
This commit is contained in:
Generated
+10
-975
File diff suppressed because it is too large
Load Diff
@@ -26,7 +26,6 @@
|
||||
"ejs": "^3.1.10",
|
||||
"license-checker": "^25.0.1",
|
||||
"node-fetch": "^2.7.0",
|
||||
"shelljs": "^0.10.0",
|
||||
"spdx-license-list": "^5.0.0"
|
||||
},
|
||||
"keywords": [
|
||||
@@ -36,7 +35,6 @@
|
||||
"devDependencies": {
|
||||
"@types/ejs": "^3.1.2",
|
||||
"@types/node": "^20.1.7",
|
||||
"@types/shelljs": "^0.8.12",
|
||||
"typescript": "^4.9.5"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import * as shell from 'shelljs';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import * as ejs from 'ejs';
|
||||
import * as path from 'path';
|
||||
import * as fs from 'fs';
|
||||
@@ -93,8 +93,45 @@ Options:
|
||||
console.log(`Running audit on ${packagePath}`);
|
||||
|
||||
const packageJson = JSON.parse(fs.readFileSync(packagePath).toString());
|
||||
const cmd = 'npm audit --json --prod';
|
||||
const jsonAudit = JSON.parse(shell.exec(cmd, { silent: true }));
|
||||
|
||||
// Run in the directory containing the package.json
|
||||
const packageDir = path.dirname(packagePath);
|
||||
|
||||
// Use spawnSync with array arguments for safer command execution (prevents shell injection)
|
||||
// Cross-platform: npm is available on PATH on all platforms (Windows, macOS, Linux)
|
||||
const result = spawnSync('npm', ['audit', '--json', '--prod'], {
|
||||
cwd: packageDir,
|
||||
encoding: 'utf-8',
|
||||
// shell: false is the default and more secure (no shell interpretation)
|
||||
shell: false,
|
||||
// Set maxBuffer to handle large audit outputs
|
||||
maxBuffer: 10 * 1024 * 1024 // 10MB
|
||||
});
|
||||
|
||||
let jsonAudit;
|
||||
|
||||
// npm audit returns non-zero exit code when vulnerabilities are found
|
||||
// We still want to parse the JSON output in this case
|
||||
if (result.error) {
|
||||
console.error('Failed to run npm audit:', result.error.message);
|
||||
reject(result.error);
|
||||
return;
|
||||
}
|
||||
|
||||
const auditOutput = result.stdout;
|
||||
if (!auditOutput) {
|
||||
console.error('npm audit produced no output');
|
||||
reject(new Error('npm audit produced no output'));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
jsonAudit = JSON.parse(auditOutput);
|
||||
} catch (parseError) {
|
||||
console.error('Failed to parse npm audit output');
|
||||
reject(parseError);
|
||||
return;
|
||||
}
|
||||
|
||||
ejs.renderFile(
|
||||
templatePath,
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
import { argv, exit } from 'node:process';
|
||||
import { parseArgs } from 'node:util';
|
||||
import * as shell from 'shelljs';
|
||||
import { spawnSync } from 'node:child_process';
|
||||
import * as path from 'path';
|
||||
import { logger } from './logger';
|
||||
import * as fs from 'fs';
|
||||
@@ -65,10 +65,22 @@ interface DiffOptions {
|
||||
* @returns URL pointing to the git remote
|
||||
*/
|
||||
function getRemote(workingDir: string): string {
|
||||
const command = 'git config --get remote.origin.url';
|
||||
const remote = shell.exec(command, { cwd: workingDir, silent: true }).toString();
|
||||
// Use spawnSync with array arguments for safer command execution (prevents shell injection)
|
||||
const result = spawnSync('git', ['config', '--get', 'remote.origin.url'], {
|
||||
cwd: workingDir,
|
||||
encoding: 'utf-8',
|
||||
shell: false
|
||||
});
|
||||
|
||||
return remote.trim();
|
||||
if (result.error) {
|
||||
throw new Error(`Failed to get git remote: ${result.error.message}`);
|
||||
}
|
||||
|
||||
if (result.status !== 0) {
|
||||
throw new Error(`git config command failed with exit code ${result.status}: ${result.stderr}`);
|
||||
}
|
||||
|
||||
return result.stdout.trim();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -87,14 +99,14 @@ function getCommits(options: DiffOptions): Array<Commit> {
|
||||
authorFilter = `bot|Alfresco Build User`;
|
||||
}
|
||||
|
||||
// Build git command arguments array for safe execution (prevents shell injection)
|
||||
const args = [
|
||||
`git`,
|
||||
`log`,
|
||||
'log',
|
||||
options.range,
|
||||
`--no-merges`,
|
||||
`--first-parent`,
|
||||
'--no-merges',
|
||||
'--first-parent',
|
||||
// this format is needed to allow parsing all characters in the commit message and safely convert to JSON
|
||||
`--format="{ ^@^hash^@^: ^@^%h^@^, ^@^author^@^: ^@^%an^@^, ^@^author_email^@^: ^@^%ae^@^, ^@^date^@^: ^@^%ad^@^, ^@^subject^@^: ^@^%s^@^ }"`
|
||||
'--format={ ^@^hash^@^: ^@^%h^@^, ^@^author^@^: ^@^%an^@^, ^@^author_email^@^: ^@^%ae^@^, ^@^date^@^: ^@^%ad^@^, ^@^subject^@^: ^@^%s^@^ }'
|
||||
];
|
||||
|
||||
if (options.max !== undefined) {
|
||||
@@ -105,9 +117,23 @@ function getCommits(options: DiffOptions): Array<Commit> {
|
||||
args.push(`--skip=${options.skip}`);
|
||||
}
|
||||
|
||||
const command = args.join(' ');
|
||||
// Use spawnSync with array arguments for safer command execution
|
||||
const result = spawnSync('git', args, {
|
||||
cwd: options.dir,
|
||||
encoding: 'utf-8',
|
||||
shell: false,
|
||||
maxBuffer: 10 * 1024 * 1024 // 10MB to handle large git logs
|
||||
});
|
||||
|
||||
let log = shell.exec(command, { cwd: options.dir, silent: true }).toString();
|
||||
if (result.error) {
|
||||
throw new Error(`Failed to get git commits: ${result.error.message}`);
|
||||
}
|
||||
|
||||
if (result.status !== 0) {
|
||||
throw new Error(`git log command failed with exit code ${result.status}: ${result.stderr}`);
|
||||
}
|
||||
|
||||
let log = result.stdout;
|
||||
|
||||
// https://stackoverflow.com/a/13928240/14644447
|
||||
log = JSON.stringify(log.trim()).slice(1, -1).replace(/\^@\^/gm, '"');
|
||||
|
||||
Generated
-83
@@ -70,7 +70,6 @@
|
||||
"@types/minimatch": "5.1.2",
|
||||
"@types/node": "^18.16.9",
|
||||
"@types/pdfjs-dist": "2.10.378",
|
||||
"@types/shelljs": "^0.8.17",
|
||||
"@types/superagent": "^4.1.22",
|
||||
"@typescript-eslint/eslint-plugin": "6.21.0",
|
||||
"@typescript-eslint/parser": "6.21.0",
|
||||
@@ -116,7 +115,6 @@
|
||||
"prettier": "3.6.2",
|
||||
"rimraf": "^6.1.2",
|
||||
"sass-loader": "16.0.5",
|
||||
"shelljs": "^0.10.0",
|
||||
"spdx-license-list": "^6.9.0",
|
||||
"stylelint": "16.20.0",
|
||||
"stylelint-config-standard-scss": "^13.1.0",
|
||||
@@ -14682,57 +14680,6 @@
|
||||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/shelljs": {
|
||||
"version": "0.8.17",
|
||||
"resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.8.17.tgz",
|
||||
"integrity": "sha512-IDksKYmQA2W9MkQjiyptbMmcQx+8+Ol6b7h6dPU5S05JyiQDSb/nZKnrMrZqGwgV6VkVdl6/SPCKPDlMRvqECg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/node": "*",
|
||||
"glob": "^11.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/shelljs/node_modules/glob": {
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-11.1.0.tgz",
|
||||
"integrity": "sha512-vuNwKSaKiqm7g0THUBu2x7ckSs3XJLXE+2ssL7/MfTGPLLcrJQ/4Uq1CjPTtO5cCIiRxqvN6Twy1qOwhL0Xjcw==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"foreground-child": "^3.3.1",
|
||||
"jackspeak": "^4.1.1",
|
||||
"minimatch": "^10.1.1",
|
||||
"minipass": "^7.1.2",
|
||||
"package-json-from-dist": "^1.0.0",
|
||||
"path-scurry": "^2.0.0"
|
||||
},
|
||||
"bin": {
|
||||
"glob": "dist/esm/bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/shelljs/node_modules/minimatch": {
|
||||
"version": "10.1.1",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.1.1.tgz",
|
||||
"integrity": "sha512-enIvLvRAFZYXJzkCYG5RKmPfrFArdLv+R+lbQ53BmIMLIry74bjKzX6iHAm8WYamJkhSSEabrWN5D97XnKObjQ==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/brace-expansion": "^5.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/sockjs": {
|
||||
"version": "0.3.36",
|
||||
"resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.36.tgz",
|
||||
@@ -23478,22 +23425,6 @@
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/jackspeak": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.1.tgz",
|
||||
"integrity": "sha512-zptv57P3GpL+O0I7VdMJNBZCu+BPHVQUk55Ft8/QCJjTVxrnJHuVuX/0Bl2A6/+2oyR/ZMEuFKwmzqqZ/U5nPQ==",
|
||||
"dev": true,
|
||||
"license": "BlueOak-1.0.0",
|
||||
"dependencies": {
|
||||
"@isaacs/cliui": "^8.0.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": "20 || >=22"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/jake": {
|
||||
"version": "10.9.4",
|
||||
"resolved": "https://registry.npmjs.org/jake/-/jake-10.9.4.tgz",
|
||||
@@ -31599,20 +31530,6 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/shelljs": {
|
||||
"version": "0.10.0",
|
||||
"resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.10.0.tgz",
|
||||
"integrity": "sha512-Jex+xw5Mg2qMZL3qnzXIfaxEtBaC4n7xifqaqtrZDdlheR70OGkydrPJWT0V1cA1k3nanC86x9FwAmQl6w3Klw==",
|
||||
"dev": true,
|
||||
"license": "BSD-3-Clause",
|
||||
"dependencies": {
|
||||
"execa": "^5.1.1",
|
||||
"fast-glob": "^3.3.2"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/side-channel": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
|
||||
|
||||
@@ -97,7 +97,6 @@
|
||||
"@types/minimatch": "5.1.2",
|
||||
"@types/node": "^18.16.9",
|
||||
"@types/pdfjs-dist": "2.10.378",
|
||||
"@types/shelljs": "^0.8.17",
|
||||
"@types/superagent": "^4.1.22",
|
||||
"@typescript-eslint/eslint-plugin": "6.21.0",
|
||||
"@typescript-eslint/parser": "6.21.0",
|
||||
@@ -143,7 +142,6 @@
|
||||
"prettier": "3.6.2",
|
||||
"rimraf": "^6.1.2",
|
||||
"sass-loader": "16.0.5",
|
||||
"shelljs": "^0.10.0",
|
||||
"spdx-license-list": "^6.9.0",
|
||||
"stylelint": "16.20.0",
|
||||
"stylelint-config-standard-scss": "^13.1.0",
|
||||
|
||||
Reference in New Issue
Block a user