@mintlify/cli 4.0.901 → 4.0.902
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/__test__/init.test.ts +82 -0
- package/__test__/openApiCheck.test.ts +17 -0
- package/bin/helpers.js +8 -2
- package/bin/init.js +13 -0
- package/bin/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +3 -3
- package/src/helpers.tsx +8 -2
- package/src/init.tsx +15 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mintlify/cli",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.902",
|
|
4
4
|
"description": "The Mintlify CLI",
|
|
5
5
|
"engines": {
|
|
6
6
|
"node": ">=18.0.0"
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@inquirer/prompts": "7.9.0",
|
|
43
43
|
"@mintlify/common": "1.0.683",
|
|
44
|
-
"@mintlify/link-rot": "3.0.
|
|
44
|
+
"@mintlify/link-rot": "3.0.841",
|
|
45
45
|
"@mintlify/models": "0.0.259",
|
|
46
46
|
"@mintlify/prebuild": "1.0.818",
|
|
47
47
|
"@mintlify/previewing": "4.0.874",
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"vitest": "2.0.4",
|
|
82
82
|
"vitest-mock-process": "1.0.4"
|
|
83
83
|
},
|
|
84
|
-
"gitHead": "
|
|
84
|
+
"gitHead": "92fa4dcf370b7711aec2d26348ab63fac87d12fb"
|
|
85
85
|
}
|
package/src/helpers.tsx
CHANGED
|
@@ -165,8 +165,14 @@ export const suppressConsoleWarnings = (): void => {
|
|
|
165
165
|
export const readLocalOpenApiFile = async (
|
|
166
166
|
filename: string
|
|
167
167
|
): Promise<Record<string, unknown> | undefined> => {
|
|
168
|
-
const
|
|
169
|
-
const
|
|
168
|
+
const baseDir = process.cwd();
|
|
169
|
+
// const pathname = path.resolve(process.cwd(), filename);
|
|
170
|
+
const resolvedPath = path.resolve(baseDir, filename);
|
|
171
|
+
const relative = path.relative(baseDir, resolvedPath);
|
|
172
|
+
if (relative.startsWith('..') || path.isAbsolute(relative)) {
|
|
173
|
+
throw new Error('Access denied: invalid path');
|
|
174
|
+
}
|
|
175
|
+
const file = await fs.readFile(resolvedPath, 'utf-8');
|
|
170
176
|
const document = yaml.load(file) as Record<string, unknown> | undefined;
|
|
171
177
|
return document;
|
|
172
178
|
};
|
package/src/init.tsx
CHANGED
|
@@ -4,6 +4,16 @@ import { docsConfigSchema } from '@mintlify/validation';
|
|
|
4
4
|
import AdmZip from 'adm-zip';
|
|
5
5
|
import fse from 'fs-extra';
|
|
6
6
|
import { Box, Text } from 'ink';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
|
|
9
|
+
const validatePathWithinCwd = (inputPath: string): void => {
|
|
10
|
+
const baseDir = process.cwd();
|
|
11
|
+
const resolvedPath = path.resolve(baseDir, inputPath);
|
|
12
|
+
const relative = path.relative(baseDir, resolvedPath);
|
|
13
|
+
if (relative.startsWith(`..${path.sep}`) || relative === '..' || path.isAbsolute(relative)) {
|
|
14
|
+
throw new Error(`Access denied: path "${inputPath}" is outside the current directory`);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
7
17
|
|
|
8
18
|
const sendOnboardingMessage = (installDir: string) => {
|
|
9
19
|
addLogs(
|
|
@@ -58,6 +68,9 @@ export async function init(
|
|
|
58
68
|
theme?: string,
|
|
59
69
|
name?: string
|
|
60
70
|
): Promise<void> {
|
|
71
|
+
// Validate path is within current working directory to prevent path traversal
|
|
72
|
+
validatePathWithinCwd(installDir);
|
|
73
|
+
|
|
61
74
|
const isInteractive = process.stdin.isTTY;
|
|
62
75
|
const isClaudeCode = process.env.CLAUDECODE === '1';
|
|
63
76
|
const isAI = !isInteractive || isClaudeCode;
|
|
@@ -106,6 +119,8 @@ export async function init(
|
|
|
106
119
|
throw new Error('Subdirectory name cannot be empty');
|
|
107
120
|
}
|
|
108
121
|
installDir = installDir === '.' ? subdir : `${installDir}/${subdir}`;
|
|
122
|
+
// Re-validate after subdirectory is appended
|
|
123
|
+
validatePathWithinCwd(installDir);
|
|
109
124
|
}
|
|
110
125
|
}
|
|
111
126
|
|