Refactor file handling to improve URL safety and enhance file viewing capabilities across components

This commit is contained in:
Marshal
2026-06-28 08:19:21 +00:00
parent b424de8436
commit da533a488d
11 changed files with 100 additions and 28 deletions

View File

@@ -12,6 +12,20 @@ export interface CreateFileInput {
file: Express.Multer.File;
}
/**
* Make a filename safe to use as a MinIO object-key segment: collapse runs of
* spaces/unsafe characters to a single underscore while keeping the dot before
* the extension. Prevents percent-encoding mismatches between the stored URL
* and the actual object key.
*/
function sanitizeObjectName(name: string): string {
return name
.normalize("NFKD")
.replace(/[^\w.\-]+/g, "_")
.replace(/_{2,}/g, "_")
.replace(/^_+|_+$/g, "");
}
@Injectable()
export class FilesService {
constructor(
@@ -21,7 +35,12 @@ export class FilesService {
async upload(input: CreateFileInput): Promise<FileRecord> {
const { resourceId, resource, code, file } = input;
const objectName = `${resource}/${resourceId}/${Date.now()}_${file.originalname}`;
// Keep the object key URL-safe so it survives the round-trip through the
// stored URL (spaces/unicode in the original name would otherwise be
// percent-encoded in the URL and no longer match the MinIO key). The
// human-readable name is preserved separately on the record below.
const safeName = sanitizeObjectName(file.originalname);
const objectName = `${resource}/${resourceId}/${Date.now()}_${safeName}`;
const url = await this.minioService.uploadFile(objectName, file.buffer, file.mimetype);
return this.filesRepository.create({