fix: block uploading already existing file name

This commit is contained in:
arc-alex
2025-12-11 15:35:41 +01:00
committed by Carlos Valente
parent f0e81c0cf0
commit 77225383a4
3 changed files with 27 additions and 7 deletions
+2 -2
View File
@@ -13,7 +13,7 @@ import sanitize from 'sanitize-filename';
import {
doesProjectExist,
handleImageUpload,
handleUploaded,
handleProjectUploaded,
} from '../../services/project-service/projectServiceUtils.js';
import * as projectService from '../../services/project-service/ProjectService.js';
@@ -129,7 +129,7 @@ export async function postProjectFile(req: Request, res: Response<MessageRespons
try {
const { filename, path } = req.file;
await handleUploaded(path, filename);
await handleProjectUploaded(path, filename);
await projectService.loadProjectFile(filename);
res.status(201).send({
@@ -9,18 +9,25 @@ import { dockerSafeRename, getFilesFromFolder, removeFileExtension } from '../..
/**
* Handles the upload of a new project file
* @throws if the file already exits
* @param filePath
* @param name
*/
export async function handleUploaded(filePath: string, name: string) {
export async function handleProjectUploaded(filePath: string, name: string) {
const newFilePath = join(publicDir.projectsDir, name);
await dockerSafeRename(filePath, newFilePath);
}
/**
* Handles the upload of a logo image
* @throws if the file already exits
* @param filePath
* @param name
* @returns
*/
export async function handleImageUpload(filePath: string, name: string): Promise<string> {
const newFilePath = join(publicDir.logoDir, name);
await dockerSafeRename(filePath, newFilePath);
return name;
}
+16 -3
View File
@@ -1,6 +1,8 @@
import { existsSync, mkdirSync, PathLike } from 'fs';
import { existsSync, mkdirSync, PathLike, constants } from 'fs';
import { readdir, copyFile, unlink } from 'fs/promises';
import { basename, join, parse } from 'path';
import { consoleError } from './console.js';
import { is } from './is.js';
/**
* @description Creates a directory if it doesn't exist
@@ -102,12 +104,23 @@ export async function copyDirectory(src: string, dest: string) {
}
/**
* @throws if the file already exits
* workaround avoids origin errors in docker deployments
* EXDEV cross-device link not permitted
*/
export async function dockerSafeRename(oldPath: PathLike, newPath: PathLike) {
await copyFile(oldPath, newPath);
await unlink(oldPath);
try {
await copyFile(oldPath, newPath, constants.COPYFILE_EXCL);
await unlink(oldPath);
} catch (error) {
// for securely reasons we should not let the error or fs leak server file path up the error chain
if (is.object(error) && 'code' in error && error.code === 'EEXIST') {
consoleError(`rename error: File already exists ${newPath}`);
throw new Error(`File already exists`);
}
consoleError(`rename error ${error}`);
throw new Error('Unknown file rename error');
}
}
/**