diff --git a/package-lock.json b/package-lock.json index a9484a9..e7c77fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4057,9 +4057,9 @@ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==" }, "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.10.tgz", + "integrity": "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA==", "dependencies": { "jake": "^10.8.5" }, @@ -5416,9 +5416,9 @@ "integrity": "sha512-GRnmB5gPyJpAhTQdSZTSp9uaPSvl09KoYcMQtsB9rQoOmzs9dH6ffeccH+Z+cv6P68Hu5bC6JjRh4Ah/mHSNRw==" }, "node_modules/follow-redirects": { - "version": "1.15.4", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.4.tgz", - "integrity": "sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", @@ -11152,9 +11152,9 @@ } }, "node_modules/tar": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.0.tgz", - "integrity": "sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.2.1.tgz", + "integrity": "sha512-DZ4yORTwrbTj/7MZYq2w+/ZFdI6OZ/f9SFHR+71gIVUZhOQPHzVCLpvRnPgyaMpfWxxk/4ONva3GQSyNIKRv6A==", "dev": true, "dependencies": { "chownr": "^2.0.0", diff --git a/package.json b/package.json index 95ab791..a6d89e6 100644 --- a/package.json +++ b/package.json @@ -99,4 +99,4 @@ "app:uninstall": "APUI" } } -} +} \ No newline at end of file diff --git a/src/commands/app/create.ts b/src/commands/app/create.ts index eea151b..38471b0 100644 --- a/src/commands/app/create.ts +++ b/src/commands/app/create.ts @@ -31,6 +31,7 @@ import { getAppName, getDirName, getOrgAppUiLocation, + sanitizePath } from "../../util"; export default class Create extends BaseCommand { @@ -386,7 +387,7 @@ export default class Create extends BaseCommand { this.sharedConfig.folderPath = resolve( dirname(this.sharedConfig.folderPath), - this.appData.name + sanitizePath(this.appData.name) ); this.sharedConfig.nameChanged = true; diff --git a/src/util/common-utils.ts b/src/util/common-utils.ts index 8c8c708..9f473bb 100644 --- a/src/util/common-utils.ts +++ b/src/util/common-utils.ts @@ -225,6 +225,10 @@ async function fetchInstalledApps( return batchRequests.flat(); } + +// To remove the relative path +const sanitizePath = (str: string) => str?.replace(/^(\.\.(\/|\\|$))+/, ''); + export { getOrganizations, getOrgAppUiLocation, @@ -237,4 +241,5 @@ export { fetchStack, uninstallApp, fetchInstalledApps, + sanitizePath }; diff --git a/src/util/fs.ts b/src/util/fs.ts index da15107..02d31d8 100644 --- a/src/util/fs.ts +++ b/src/util/fs.ts @@ -1,21 +1,22 @@ import { existsSync, readdirSync, writeFileSync, mkdirSync } from "fs"; import { resolve } from "path"; import config from "../config"; -import messages, {$t} from "../messages"; +import messages, { $t } from "../messages"; import { LogFn } from "../types"; import { cliux } from "@contentstack/cli-utilities"; +import { sanitizePath } from './common-utils' -export async function writeFile(dir: string=process.cwd(), force: boolean=false, data: Record | undefined={}, log: LogFn=console.log) { +export async function writeFile(dir: string = process.cwd(), force: boolean = false, data: Record | undefined = {}, log: LogFn = console.log) { await ensureDirectoryExists(dir) const files = readdirSync(dir) const latestFileName = files.filter(fileName => fileName.match(new RegExp(config.defaultAppFileName))).pop()?.split('.')[0] || config.defaultAppFileName; - let target = resolve(dir, `${latestFileName}.json`) + let target = resolve(sanitizePath(dir), `${sanitizePath(latestFileName)}.json`) if (existsSync(target)) { const userConfirmation: boolean = force || (await cliux.confirm($t(messages.FILE_ALREADY_EXISTS, { file: `${config.defaultAppFileName}.json` }))) if (userConfirmation) { - target = resolve(dir, `${config.defaultAppFileName}.json`); + target = resolve(sanitizePath(dir), `${sanitizePath(config.defaultAppFileName)}.json`); } else { - target = resolve(dir, `${incrementName(latestFileName)}.json`); + target = resolve(sanitizePath(dir), `${sanitizePath(incrementName(latestFileName))}.json`); } } await writeFileSync(target, JSON.stringify(data)) @@ -24,10 +25,10 @@ export async function writeFile(dir: string=process.cwd(), force: boolean=false, async function ensureDirectoryExists(dir: string) { if (!existsSync(dir)) { - await mkdirSync(dir, {recursive: true}) + await mkdirSync(dir, { recursive: true }) } } function incrementName(name: string) { - return `${config.defaultAppFileName}${Number(name.split(config.defaultAppFileName).pop())+1}` + return `${config.defaultAppFileName}${Number(name.split(config.defaultAppFileName).pop()) + 1}` } \ No newline at end of file diff --git a/src/util/inquirer.ts b/src/util/inquirer.ts index c55142e..4d6bfb8 100644 --- a/src/util/inquirer.ts +++ b/src/util/inquirer.ts @@ -20,6 +20,7 @@ import { fetchAppInstallations, fetchInstalledApps, fetchApps, + sanitizePath, } from "./common-utils"; /** @@ -64,14 +65,14 @@ async function getDirName(path: string): Promise { return $t(errors.INVALID_NAME, { min: "3", max: "50" }); } - if (existsSync(join(basePath, name))) { + if (existsSync(join(sanitizePath(basePath), sanitizePath(name)))) { return messages.DIR_EXIST; } return true; }, }) - .then((name) => join(basePath, name as string)); + .then((name) => join(sanitizePath(basePath), sanitizePath(name as string))); } /**