@dexto/tools-filesystem 1.5.0
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/LICENSE +44 -0
- package/dist/directory-approval.integration.test.cjs +467 -0
- package/dist/directory-approval.integration.test.d.cts +2 -0
- package/dist/directory-approval.integration.test.d.ts +2 -0
- package/dist/directory-approval.integration.test.js +444 -0
- package/dist/edit-file-tool.cjs +181 -0
- package/dist/edit-file-tool.d.cts +17 -0
- package/dist/edit-file-tool.d.ts +17 -0
- package/dist/edit-file-tool.js +147 -0
- package/dist/error-codes.cjs +53 -0
- package/dist/error-codes.d.cts +32 -0
- package/dist/error-codes.d.ts +32 -0
- package/dist/error-codes.js +29 -0
- package/dist/errors.cjs +302 -0
- package/dist/errors.d.cts +112 -0
- package/dist/errors.d.ts +112 -0
- package/dist/errors.js +278 -0
- package/dist/file-tool-types.cjs +16 -0
- package/dist/file-tool-types.d.cts +46 -0
- package/dist/file-tool-types.d.ts +46 -0
- package/dist/file-tool-types.js +0 -0
- package/dist/filesystem-service.cjs +526 -0
- package/dist/filesystem-service.d.cts +107 -0
- package/dist/filesystem-service.d.ts +107 -0
- package/dist/filesystem-service.js +492 -0
- package/dist/glob-files-tool.cjs +70 -0
- package/dist/glob-files-tool.d.cts +16 -0
- package/dist/glob-files-tool.d.ts +16 -0
- package/dist/glob-files-tool.js +46 -0
- package/dist/grep-content-tool.cjs +86 -0
- package/dist/grep-content-tool.d.cts +16 -0
- package/dist/grep-content-tool.d.ts +16 -0
- package/dist/grep-content-tool.js +62 -0
- package/dist/index.cjs +55 -0
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +22 -0
- package/dist/path-validator.cjs +232 -0
- package/dist/path-validator.d.cts +90 -0
- package/dist/path-validator.d.ts +90 -0
- package/dist/path-validator.js +198 -0
- package/dist/path-validator.test.cjs +444 -0
- package/dist/path-validator.test.d.cts +2 -0
- package/dist/path-validator.test.d.ts +2 -0
- package/dist/path-validator.test.js +443 -0
- package/dist/read-file-tool.cjs +117 -0
- package/dist/read-file-tool.d.cts +17 -0
- package/dist/read-file-tool.d.ts +17 -0
- package/dist/read-file-tool.js +83 -0
- package/dist/tool-provider.cjs +108 -0
- package/dist/tool-provider.d.cts +74 -0
- package/dist/tool-provider.d.ts +74 -0
- package/dist/tool-provider.js +84 -0
- package/dist/types.cjs +16 -0
- package/dist/types.d.cts +172 -0
- package/dist/types.d.ts +172 -0
- package/dist/types.js +0 -0
- package/dist/write-file-tool.cjs +177 -0
- package/dist/write-file-tool.d.cts +17 -0
- package/dist/write-file-tool.d.ts +17 -0
- package/dist/write-file-tool.js +143 -0
- package/package.json +42 -0
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var import_vitest = require("vitest");
|
|
3
|
+
var import_path_validator = require("./path-validator.js");
|
|
4
|
+
const createMockLogger = () => ({
|
|
5
|
+
debug: import_vitest.vi.fn(),
|
|
6
|
+
info: import_vitest.vi.fn(),
|
|
7
|
+
warn: import_vitest.vi.fn(),
|
|
8
|
+
error: import_vitest.vi.fn(),
|
|
9
|
+
createChild: import_vitest.vi.fn().mockReturnThis()
|
|
10
|
+
});
|
|
11
|
+
(0, import_vitest.describe)("PathValidator", () => {
|
|
12
|
+
let mockLogger;
|
|
13
|
+
(0, import_vitest.beforeEach)(() => {
|
|
14
|
+
mockLogger = createMockLogger();
|
|
15
|
+
import_vitest.vi.clearAllMocks();
|
|
16
|
+
});
|
|
17
|
+
(0, import_vitest.describe)("validatePath", () => {
|
|
18
|
+
(0, import_vitest.describe)("Empty and Invalid Paths", () => {
|
|
19
|
+
(0, import_vitest.it)("should reject empty path", () => {
|
|
20
|
+
const validator = new import_path_validator.PathValidator(
|
|
21
|
+
{
|
|
22
|
+
allowedPaths: ["/home/user/project"],
|
|
23
|
+
blockedPaths: [],
|
|
24
|
+
blockedExtensions: [],
|
|
25
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
26
|
+
enableBackups: false,
|
|
27
|
+
backupRetentionDays: 7,
|
|
28
|
+
workingDirectory: "/home/user/project"
|
|
29
|
+
},
|
|
30
|
+
mockLogger
|
|
31
|
+
);
|
|
32
|
+
const result = validator.validatePath("");
|
|
33
|
+
(0, import_vitest.expect)(result.isValid).toBe(false);
|
|
34
|
+
(0, import_vitest.expect)(result.error).toBe("Path cannot be empty");
|
|
35
|
+
});
|
|
36
|
+
(0, import_vitest.it)("should reject whitespace-only path", () => {
|
|
37
|
+
const validator = new import_path_validator.PathValidator(
|
|
38
|
+
{
|
|
39
|
+
allowedPaths: ["/home/user/project"],
|
|
40
|
+
blockedPaths: [],
|
|
41
|
+
blockedExtensions: [],
|
|
42
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
43
|
+
enableBackups: false,
|
|
44
|
+
backupRetentionDays: 7,
|
|
45
|
+
workingDirectory: "/home/user/project"
|
|
46
|
+
},
|
|
47
|
+
mockLogger
|
|
48
|
+
);
|
|
49
|
+
const result = validator.validatePath(" ");
|
|
50
|
+
(0, import_vitest.expect)(result.isValid).toBe(false);
|
|
51
|
+
(0, import_vitest.expect)(result.error).toBe("Path cannot be empty");
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
(0, import_vitest.describe)("Allowed Paths", () => {
|
|
55
|
+
(0, import_vitest.it)("should allow paths within allowed directories", () => {
|
|
56
|
+
const validator = new import_path_validator.PathValidator(
|
|
57
|
+
{
|
|
58
|
+
allowedPaths: ["/home/user/project"],
|
|
59
|
+
blockedPaths: [],
|
|
60
|
+
blockedExtensions: [],
|
|
61
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
62
|
+
enableBackups: false,
|
|
63
|
+
backupRetentionDays: 7,
|
|
64
|
+
workingDirectory: "/home/user/project"
|
|
65
|
+
},
|
|
66
|
+
mockLogger
|
|
67
|
+
);
|
|
68
|
+
const result = validator.validatePath("/home/user/project/src/file.ts");
|
|
69
|
+
(0, import_vitest.expect)(result.isValid).toBe(true);
|
|
70
|
+
(0, import_vitest.expect)(result.normalizedPath).toBeDefined();
|
|
71
|
+
});
|
|
72
|
+
(0, import_vitest.it)("should allow relative paths within working directory", () => {
|
|
73
|
+
const validator = new import_path_validator.PathValidator(
|
|
74
|
+
{
|
|
75
|
+
allowedPaths: ["/home/user/project"],
|
|
76
|
+
blockedPaths: [],
|
|
77
|
+
blockedExtensions: [],
|
|
78
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
79
|
+
enableBackups: false,
|
|
80
|
+
backupRetentionDays: 7,
|
|
81
|
+
workingDirectory: "/home/user/project"
|
|
82
|
+
},
|
|
83
|
+
mockLogger
|
|
84
|
+
);
|
|
85
|
+
const result = validator.validatePath("src/file.ts");
|
|
86
|
+
(0, import_vitest.expect)(result.isValid).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
(0, import_vitest.it)("should reject paths outside allowed directories", () => {
|
|
89
|
+
const validator = new import_path_validator.PathValidator(
|
|
90
|
+
{
|
|
91
|
+
allowedPaths: ["/home/user/project"],
|
|
92
|
+
blockedPaths: [],
|
|
93
|
+
blockedExtensions: [],
|
|
94
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
95
|
+
enableBackups: false,
|
|
96
|
+
backupRetentionDays: 7,
|
|
97
|
+
workingDirectory: "/home/user/project"
|
|
98
|
+
},
|
|
99
|
+
mockLogger
|
|
100
|
+
);
|
|
101
|
+
const result = validator.validatePath("/external/project/file.ts");
|
|
102
|
+
(0, import_vitest.expect)(result.isValid).toBe(false);
|
|
103
|
+
(0, import_vitest.expect)(result.error).toContain("not within allowed paths");
|
|
104
|
+
});
|
|
105
|
+
(0, import_vitest.it)("should allow all paths when allowedPaths is empty", () => {
|
|
106
|
+
const validator = new import_path_validator.PathValidator(
|
|
107
|
+
{
|
|
108
|
+
allowedPaths: [],
|
|
109
|
+
blockedPaths: [],
|
|
110
|
+
blockedExtensions: [],
|
|
111
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
112
|
+
enableBackups: false,
|
|
113
|
+
backupRetentionDays: 7,
|
|
114
|
+
workingDirectory: "/home/user/project"
|
|
115
|
+
},
|
|
116
|
+
mockLogger
|
|
117
|
+
);
|
|
118
|
+
const result = validator.validatePath("/anywhere/file.ts");
|
|
119
|
+
(0, import_vitest.expect)(result.isValid).toBe(true);
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
(0, import_vitest.describe)("Path Traversal Detection", () => {
|
|
123
|
+
(0, import_vitest.it)("should reject path traversal attempts", () => {
|
|
124
|
+
const validator = new import_path_validator.PathValidator(
|
|
125
|
+
{
|
|
126
|
+
allowedPaths: ["/home/user/project"],
|
|
127
|
+
blockedPaths: [],
|
|
128
|
+
blockedExtensions: [],
|
|
129
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
130
|
+
enableBackups: false,
|
|
131
|
+
backupRetentionDays: 7,
|
|
132
|
+
workingDirectory: "/home/user/project"
|
|
133
|
+
},
|
|
134
|
+
mockLogger
|
|
135
|
+
);
|
|
136
|
+
const result = validator.validatePath("/home/user/project/../../../etc/passwd");
|
|
137
|
+
(0, import_vitest.expect)(result.isValid).toBe(false);
|
|
138
|
+
(0, import_vitest.expect)(result.error).toBe("Path traversal detected");
|
|
139
|
+
});
|
|
140
|
+
});
|
|
141
|
+
(0, import_vitest.describe)("Blocked Paths", () => {
|
|
142
|
+
(0, import_vitest.it)("should reject paths in blocked directories", () => {
|
|
143
|
+
const validator = new import_path_validator.PathValidator(
|
|
144
|
+
{
|
|
145
|
+
allowedPaths: ["/home/user/project"],
|
|
146
|
+
blockedPaths: [".git", "node_modules"],
|
|
147
|
+
blockedExtensions: [],
|
|
148
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
149
|
+
enableBackups: false,
|
|
150
|
+
backupRetentionDays: 7,
|
|
151
|
+
workingDirectory: "/home/user/project"
|
|
152
|
+
},
|
|
153
|
+
mockLogger
|
|
154
|
+
);
|
|
155
|
+
const result = validator.validatePath("/home/user/project/.git/config");
|
|
156
|
+
(0, import_vitest.expect)(result.isValid).toBe(false);
|
|
157
|
+
(0, import_vitest.expect)(result.error).toContain("blocked");
|
|
158
|
+
});
|
|
159
|
+
(0, import_vitest.it)("should reject paths in node_modules", () => {
|
|
160
|
+
const validator = new import_path_validator.PathValidator(
|
|
161
|
+
{
|
|
162
|
+
allowedPaths: ["/home/user/project"],
|
|
163
|
+
blockedPaths: ["node_modules"],
|
|
164
|
+
blockedExtensions: [],
|
|
165
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
166
|
+
enableBackups: false,
|
|
167
|
+
backupRetentionDays: 7,
|
|
168
|
+
workingDirectory: "/home/user/project"
|
|
169
|
+
},
|
|
170
|
+
mockLogger
|
|
171
|
+
);
|
|
172
|
+
const result = validator.validatePath(
|
|
173
|
+
"/home/user/project/node_modules/lodash/index.js"
|
|
174
|
+
);
|
|
175
|
+
(0, import_vitest.expect)(result.isValid).toBe(false);
|
|
176
|
+
(0, import_vitest.expect)(result.error).toContain("blocked");
|
|
177
|
+
});
|
|
178
|
+
});
|
|
179
|
+
(0, import_vitest.describe)("Blocked Extensions", () => {
|
|
180
|
+
(0, import_vitest.it)("should reject files with blocked extensions", () => {
|
|
181
|
+
const validator = new import_path_validator.PathValidator(
|
|
182
|
+
{
|
|
183
|
+
allowedPaths: ["/home/user/project"],
|
|
184
|
+
blockedPaths: [],
|
|
185
|
+
blockedExtensions: [".exe", ".dll"],
|
|
186
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
187
|
+
enableBackups: false,
|
|
188
|
+
backupRetentionDays: 7,
|
|
189
|
+
workingDirectory: "/home/user/project"
|
|
190
|
+
},
|
|
191
|
+
mockLogger
|
|
192
|
+
);
|
|
193
|
+
const result = validator.validatePath("/home/user/project/malware.exe");
|
|
194
|
+
(0, import_vitest.expect)(result.isValid).toBe(false);
|
|
195
|
+
(0, import_vitest.expect)(result.error).toContain(".exe is not allowed");
|
|
196
|
+
});
|
|
197
|
+
(0, import_vitest.it)("should handle extensions without leading dot", () => {
|
|
198
|
+
const validator = new import_path_validator.PathValidator(
|
|
199
|
+
{
|
|
200
|
+
allowedPaths: ["/home/user/project"],
|
|
201
|
+
blockedPaths: [],
|
|
202
|
+
blockedExtensions: ["exe", "dll"],
|
|
203
|
+
// No leading dot
|
|
204
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
205
|
+
enableBackups: false,
|
|
206
|
+
backupRetentionDays: 7,
|
|
207
|
+
workingDirectory: "/home/user/project"
|
|
208
|
+
},
|
|
209
|
+
mockLogger
|
|
210
|
+
);
|
|
211
|
+
const result = validator.validatePath("/home/user/project/file.exe");
|
|
212
|
+
(0, import_vitest.expect)(result.isValid).toBe(false);
|
|
213
|
+
});
|
|
214
|
+
(0, import_vitest.it)("should be case-insensitive for extensions", () => {
|
|
215
|
+
const validator = new import_path_validator.PathValidator(
|
|
216
|
+
{
|
|
217
|
+
allowedPaths: ["/home/user/project"],
|
|
218
|
+
blockedPaths: [],
|
|
219
|
+
blockedExtensions: [".exe"],
|
|
220
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
221
|
+
enableBackups: false,
|
|
222
|
+
backupRetentionDays: 7,
|
|
223
|
+
workingDirectory: "/home/user/project"
|
|
224
|
+
},
|
|
225
|
+
mockLogger
|
|
226
|
+
);
|
|
227
|
+
const result = validator.validatePath("/home/user/project/file.EXE");
|
|
228
|
+
(0, import_vitest.expect)(result.isValid).toBe(false);
|
|
229
|
+
});
|
|
230
|
+
});
|
|
231
|
+
(0, import_vitest.describe)("Directory Approval Checker Integration", () => {
|
|
232
|
+
(0, import_vitest.it)("should consult approval checker for external paths", () => {
|
|
233
|
+
const validator = new import_path_validator.PathValidator(
|
|
234
|
+
{
|
|
235
|
+
allowedPaths: ["/home/user/project"],
|
|
236
|
+
blockedPaths: [],
|
|
237
|
+
blockedExtensions: [],
|
|
238
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
239
|
+
enableBackups: false,
|
|
240
|
+
backupRetentionDays: 7,
|
|
241
|
+
workingDirectory: "/home/user/project"
|
|
242
|
+
},
|
|
243
|
+
mockLogger
|
|
244
|
+
);
|
|
245
|
+
let result = validator.validatePath("/external/project/file.ts");
|
|
246
|
+
(0, import_vitest.expect)(result.isValid).toBe(false);
|
|
247
|
+
const approvalChecker = (filePath) => {
|
|
248
|
+
return filePath.startsWith("/external/project");
|
|
249
|
+
};
|
|
250
|
+
validator.setDirectoryApprovalChecker(approvalChecker);
|
|
251
|
+
result = validator.validatePath("/external/project/file.ts");
|
|
252
|
+
(0, import_vitest.expect)(result.isValid).toBe(true);
|
|
253
|
+
});
|
|
254
|
+
(0, import_vitest.it)("should not use approval checker for config-allowed paths", () => {
|
|
255
|
+
const approvalChecker = import_vitest.vi.fn().mockReturnValue(false);
|
|
256
|
+
const validator = new import_path_validator.PathValidator(
|
|
257
|
+
{
|
|
258
|
+
allowedPaths: ["/home/user/project"],
|
|
259
|
+
blockedPaths: [],
|
|
260
|
+
blockedExtensions: [],
|
|
261
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
262
|
+
enableBackups: false,
|
|
263
|
+
backupRetentionDays: 7,
|
|
264
|
+
workingDirectory: "/home/user/project"
|
|
265
|
+
},
|
|
266
|
+
mockLogger
|
|
267
|
+
);
|
|
268
|
+
validator.setDirectoryApprovalChecker(approvalChecker);
|
|
269
|
+
const result = validator.validatePath("/home/user/project/src/file.ts");
|
|
270
|
+
(0, import_vitest.expect)(result.isValid).toBe(true);
|
|
271
|
+
(0, import_vitest.expect)(approvalChecker).not.toHaveBeenCalled();
|
|
272
|
+
});
|
|
273
|
+
});
|
|
274
|
+
});
|
|
275
|
+
(0, import_vitest.describe)("isPathWithinAllowed", () => {
|
|
276
|
+
(0, import_vitest.it)("should return true for paths within config-allowed directories", () => {
|
|
277
|
+
const validator = new import_path_validator.PathValidator(
|
|
278
|
+
{
|
|
279
|
+
allowedPaths: ["/home/user/project"],
|
|
280
|
+
blockedPaths: [],
|
|
281
|
+
blockedExtensions: [],
|
|
282
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
283
|
+
enableBackups: false,
|
|
284
|
+
backupRetentionDays: 7,
|
|
285
|
+
workingDirectory: "/home/user/project"
|
|
286
|
+
},
|
|
287
|
+
mockLogger
|
|
288
|
+
);
|
|
289
|
+
(0, import_vitest.expect)(validator.isPathWithinAllowed("/home/user/project/src/file.ts")).toBe(true);
|
|
290
|
+
(0, import_vitest.expect)(validator.isPathWithinAllowed("/home/user/project/deep/nested/file.ts")).toBe(
|
|
291
|
+
true
|
|
292
|
+
);
|
|
293
|
+
});
|
|
294
|
+
(0, import_vitest.it)("should return false for paths outside config-allowed directories", () => {
|
|
295
|
+
const validator = new import_path_validator.PathValidator(
|
|
296
|
+
{
|
|
297
|
+
allowedPaths: ["/home/user/project"],
|
|
298
|
+
blockedPaths: [],
|
|
299
|
+
blockedExtensions: [],
|
|
300
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
301
|
+
enableBackups: false,
|
|
302
|
+
backupRetentionDays: 7,
|
|
303
|
+
workingDirectory: "/home/user/project"
|
|
304
|
+
},
|
|
305
|
+
mockLogger
|
|
306
|
+
);
|
|
307
|
+
(0, import_vitest.expect)(validator.isPathWithinAllowed("/external/project/file.ts")).toBe(false);
|
|
308
|
+
(0, import_vitest.expect)(validator.isPathWithinAllowed("/home/user/other/file.ts")).toBe(false);
|
|
309
|
+
});
|
|
310
|
+
(0, import_vitest.it)("should NOT consult approval checker (used for prompting decisions)", () => {
|
|
311
|
+
const approvalChecker = import_vitest.vi.fn().mockReturnValue(true);
|
|
312
|
+
const validator = new import_path_validator.PathValidator(
|
|
313
|
+
{
|
|
314
|
+
allowedPaths: ["/home/user/project"],
|
|
315
|
+
blockedPaths: [],
|
|
316
|
+
blockedExtensions: [],
|
|
317
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
318
|
+
enableBackups: false,
|
|
319
|
+
backupRetentionDays: 7,
|
|
320
|
+
workingDirectory: "/home/user/project"
|
|
321
|
+
},
|
|
322
|
+
mockLogger
|
|
323
|
+
);
|
|
324
|
+
validator.setDirectoryApprovalChecker(approvalChecker);
|
|
325
|
+
(0, import_vitest.expect)(validator.isPathWithinAllowed("/external/project/file.ts")).toBe(false);
|
|
326
|
+
(0, import_vitest.expect)(approvalChecker).not.toHaveBeenCalled();
|
|
327
|
+
});
|
|
328
|
+
(0, import_vitest.it)("should return false for empty path", () => {
|
|
329
|
+
const validator = new import_path_validator.PathValidator(
|
|
330
|
+
{
|
|
331
|
+
allowedPaths: ["/home/user/project"],
|
|
332
|
+
blockedPaths: [],
|
|
333
|
+
blockedExtensions: [],
|
|
334
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
335
|
+
enableBackups: false,
|
|
336
|
+
backupRetentionDays: 7,
|
|
337
|
+
workingDirectory: "/home/user/project"
|
|
338
|
+
},
|
|
339
|
+
mockLogger
|
|
340
|
+
);
|
|
341
|
+
(0, import_vitest.expect)(validator.isPathWithinAllowed("")).toBe(false);
|
|
342
|
+
(0, import_vitest.expect)(validator.isPathWithinAllowed(" ")).toBe(false);
|
|
343
|
+
});
|
|
344
|
+
(0, import_vitest.it)("should return true when allowedPaths is empty (all paths allowed)", () => {
|
|
345
|
+
const validator = new import_path_validator.PathValidator(
|
|
346
|
+
{
|
|
347
|
+
allowedPaths: [],
|
|
348
|
+
blockedPaths: [],
|
|
349
|
+
blockedExtensions: [],
|
|
350
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
351
|
+
enableBackups: false,
|
|
352
|
+
backupRetentionDays: 7,
|
|
353
|
+
workingDirectory: "/home/user/project"
|
|
354
|
+
},
|
|
355
|
+
mockLogger
|
|
356
|
+
);
|
|
357
|
+
(0, import_vitest.expect)(validator.isPathWithinAllowed("/anywhere/file.ts")).toBe(true);
|
|
358
|
+
});
|
|
359
|
+
});
|
|
360
|
+
(0, import_vitest.describe)("Path Containment (Parent Directory Coverage)", () => {
|
|
361
|
+
(0, import_vitest.it)("should recognize that approving parent covers child paths", () => {
|
|
362
|
+
const validator = new import_path_validator.PathValidator(
|
|
363
|
+
{
|
|
364
|
+
allowedPaths: ["/external/sub"],
|
|
365
|
+
blockedPaths: [],
|
|
366
|
+
blockedExtensions: [],
|
|
367
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
368
|
+
enableBackups: false,
|
|
369
|
+
backupRetentionDays: 7,
|
|
370
|
+
workingDirectory: "/home/user/project"
|
|
371
|
+
},
|
|
372
|
+
mockLogger
|
|
373
|
+
);
|
|
374
|
+
(0, import_vitest.expect)(validator.isPathWithinAllowed("/external/sub/deep/nested/file.ts")).toBe(true);
|
|
375
|
+
});
|
|
376
|
+
(0, import_vitest.it)("should not allow sibling directories", () => {
|
|
377
|
+
const validator = new import_path_validator.PathValidator(
|
|
378
|
+
{
|
|
379
|
+
allowedPaths: ["/external/sub"],
|
|
380
|
+
blockedPaths: [],
|
|
381
|
+
blockedExtensions: [],
|
|
382
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
383
|
+
enableBackups: false,
|
|
384
|
+
backupRetentionDays: 7,
|
|
385
|
+
workingDirectory: "/home/user/project"
|
|
386
|
+
},
|
|
387
|
+
mockLogger
|
|
388
|
+
);
|
|
389
|
+
(0, import_vitest.expect)(validator.isPathWithinAllowed("/external/other/file.ts")).toBe(false);
|
|
390
|
+
});
|
|
391
|
+
(0, import_vitest.it)("should not allow parent directories when child is approved", () => {
|
|
392
|
+
const validator = new import_path_validator.PathValidator(
|
|
393
|
+
{
|
|
394
|
+
allowedPaths: ["/external/sub/deep"],
|
|
395
|
+
blockedPaths: [],
|
|
396
|
+
blockedExtensions: [],
|
|
397
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
398
|
+
enableBackups: false,
|
|
399
|
+
backupRetentionDays: 7,
|
|
400
|
+
workingDirectory: "/home/user/project"
|
|
401
|
+
},
|
|
402
|
+
mockLogger
|
|
403
|
+
);
|
|
404
|
+
(0, import_vitest.expect)(validator.isPathWithinAllowed("/external/sub/file.ts")).toBe(false);
|
|
405
|
+
});
|
|
406
|
+
});
|
|
407
|
+
(0, import_vitest.describe)("getAllowedPaths and getBlockedPaths", () => {
|
|
408
|
+
(0, import_vitest.it)("should return normalized allowed paths", () => {
|
|
409
|
+
const validator = new import_path_validator.PathValidator(
|
|
410
|
+
{
|
|
411
|
+
allowedPaths: [".", "./src"],
|
|
412
|
+
blockedPaths: [],
|
|
413
|
+
blockedExtensions: [],
|
|
414
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
415
|
+
enableBackups: false,
|
|
416
|
+
backupRetentionDays: 7,
|
|
417
|
+
workingDirectory: "/home/user/project"
|
|
418
|
+
},
|
|
419
|
+
mockLogger
|
|
420
|
+
);
|
|
421
|
+
const allowedPaths = validator.getAllowedPaths();
|
|
422
|
+
(0, import_vitest.expect)(allowedPaths).toHaveLength(2);
|
|
423
|
+
(0, import_vitest.expect)(allowedPaths[0]).toBe("/home/user/project");
|
|
424
|
+
(0, import_vitest.expect)(allowedPaths[1]).toBe("/home/user/project/src");
|
|
425
|
+
});
|
|
426
|
+
(0, import_vitest.it)("should return blocked paths", () => {
|
|
427
|
+
const validator = new import_path_validator.PathValidator(
|
|
428
|
+
{
|
|
429
|
+
allowedPaths: ["/home/user/project"],
|
|
430
|
+
blockedPaths: [".git", "node_modules"],
|
|
431
|
+
blockedExtensions: [],
|
|
432
|
+
maxFileSize: 10 * 1024 * 1024,
|
|
433
|
+
enableBackups: false,
|
|
434
|
+
backupRetentionDays: 7,
|
|
435
|
+
workingDirectory: "/home/user/project"
|
|
436
|
+
},
|
|
437
|
+
mockLogger
|
|
438
|
+
);
|
|
439
|
+
const blockedPaths = validator.getBlockedPaths();
|
|
440
|
+
(0, import_vitest.expect)(blockedPaths).toContain(".git");
|
|
441
|
+
(0, import_vitest.expect)(blockedPaths).toContain("node_modules");
|
|
442
|
+
});
|
|
443
|
+
});
|
|
444
|
+
});
|