Files
foka-ci/apps/server/libs/path-validator.ts
hurole b5c550f5c5 feat(project): add workspace directory configuration and management
- Add projectDir field to Project model for workspace directory management
- Implement workspace directory creation, validation and Git initialization
- Add workspace status query endpoint with directory info and Git status
- Create GitManager for Git repository operations (clone, branch, commit info)
- Add PathValidator for secure path validation and traversal attack prevention
- Implement execution queue with concurrency control for build tasks

- Refactor project list UI to remove edit/delete actions from cards
- Add project settings tab in detail page with edit/delete functionality
- Add icons to all tabs (History, Code, Settings)
- Implement time formatting with dayjs in YYYY-MM-DD HH:mm:ss format
- Display all timestamps using browser's local timezone

- Update PipelineRunner to use workspace directory for command execution
- Add workspace status card showing directory path, size, Git info
- Enhance CreateProjectModal with repository URL validation
2026-01-03 00:54:57 +08:00

68 lines
1.6 KiB
TypeScript

/**
* 路径验证工具
* 用于验证项目工作目录路径的合法性
*/
import path from 'node:path';
import { z } from 'zod';
/**
* 项目目录路径验证schema
*/
export const projectDirSchema = z
.string()
.min(1, '工作目录路径不能为空')
.refine(path.isAbsolute, '工作目录路径必须是绝对路径')
.refine((v) => !v.includes('..'), '不能包含路径遍历字符')
.refine((v) => !v.includes('~'), '不能包含用户目录符号')
.refine((v) => !/[<>:"|?*\x00-\x1f]/.test(v), '包含非法字符')
.refine((v) => path.normalize(v) === v, '路径格式不规范');
/**
* 验证路径格式
* @param dirPath 待验证的路径
* @returns 验证结果
*/
export function validateProjectDir(dirPath: string): {
valid: boolean;
error?: string;
} {
try {
projectDirSchema.parse(dirPath);
return { valid: true };
} catch (error) {
if (error instanceof z.ZodError) {
return { valid: false, error: error.issues[0].message };
}
return { valid: false, error: '路径验证失败' };
}
}
/**
* 检查路径是否为绝对路径
*/
export function isAbsolutePath(dirPath: string): boolean {
return path.isAbsolute(dirPath);
}
/**
* 检查路径是否包含非法字符
*/
export function hasIllegalCharacters(dirPath: string): boolean {
return /[<>:"|?*\x00-\x1f]/.test(dirPath);
}
/**
* 检查路径是否包含路径遍历
*/
export function hasPathTraversal(dirPath: string): boolean {
return dirPath.includes('..') || dirPath.includes('~');
}
/**
* 规范化路径
*/
export function normalizePath(dirPath: string): string {
return path.normalize(dirPath);
}