fix persian name bug

This commit is contained in:
2026-05-21 09:43:20 +03:30
parent c7b5c4dca5
commit 1f995085b7
+23 -5
View File
@@ -44,9 +44,9 @@ export class S3Service {
try { try {
const sanitizedMetadata = metadata const sanitizedMetadata = metadata
? Object.entries(metadata).reduce( ? Object.entries(metadata).reduce(
(acc, [key, value]) => { (acc, [metaKey, value]) => {
// Encode all values to be ASCII-safe // S3 user metadata must be US-ASCII; base64 keeps signing stable for Unicode names
acc[key] = encodeURIComponent(value); acc[metaKey] = Buffer.from(value, 'utf8').toString('base64');
return acc; return acc;
}, },
{} as Record<string, string>, {} as Record<string, string>,
@@ -63,7 +63,8 @@ export class S3Service {
await this.s3Client.send(command); await this.s3Client.send(command);
const url = `${this.endpointUrl}/${this.bucketName}/${key}`; const encodedKey = key.split('/').map(segment => encodeURIComponent(segment)).join('/');
const url = `${this.endpointUrl}/${this.bucketName}/${encodedKey}`;
this.logger.log(`File uploaded to S3: ${key}`); this.logger.log(`File uploaded to S3: ${key}`);
@@ -144,7 +145,7 @@ export class S3Service {
generateFileKey(originalName: string, fileType: FileType): string { generateFileKey(originalName: string, fileType: FileType): string {
const timestamp = Date.now(); const timestamp = Date.now();
const randomSuffix = randomInt(1000000, 9999999); const randomSuffix = randomInt(1000000, 9999999);
const extension = originalName.split('.').pop(); const extension = this.extractSafeExtension(originalName);
const basePathMap: Record<FileType, string> = { const basePathMap: Record<FileType, string> = {
image: 'images', image: 'images',
@@ -158,4 +159,21 @@ export class S3Service {
const basePath = basePathMap[fileType]; const basePath = basePathMap[fileType];
return `${basePath}/${timestamp}-${randomSuffix}.${extension}`; return `${basePath}/${timestamp}-${randomSuffix}.${extension}`;
} }
/**
* Extract a safe ASCII extension so Persian/spaced names never end up in the S3 object key.
*/
private extractSafeExtension(originalName: string): string {
const basename = originalName.replace(/\\/g, '/').split('/').pop() ?? 'file';
const lastDot = basename.lastIndexOf('.');
if (lastDot > 0 && lastDot < basename.length - 1) {
const ext = basename.slice(lastDot + 1).toLowerCase();
if (/^[a-z0-9]{1,16}$/.test(ext)) {
return ext;
}
}
return 'bin';
}
} }