This commit is contained in:
pandeymangg
2025-09-08 11:14:14 +05:30
parent fb38a606f9
commit 8fafc4f940
15 changed files with 18 additions and 26 deletions
@@ -104,7 +104,7 @@ export const POST = withV1ApiWrapper({
if (!signedUrlResponse.ok) {
logger.error({ error: signedUrlResponse.error }, "Error getting signed url for upload");
const errorResponse = getErrorResponseFromStorageError(signedUrlResponse.error);
const errorResponse = getErrorResponseFromStorageError(signedUrlResponse.error, { fileName });
return {
response: errorResponse,
};
@@ -55,7 +55,7 @@ export const POST = withV1ApiWrapper({
if (!signedUrlResponse.ok) {
logger.error({ error: signedUrlResponse.error }, "Error getting signed url for upload");
const errorResponse = getErrorResponseFromStorageError(signedUrlResponse.error);
const errorResponse = getErrorResponseFromStorageError(signedUrlResponse.error, { fileName });
return {
response: errorResponse,
};
-2
View File
@@ -577,8 +577,6 @@
"contacts_table_refresh": "Kontakte aktualisieren",
"contacts_table_refresh_success": "Kontakte erfolgreich aktualisiert",
"delete_contact_confirmation": "Dies wird alle Umfrageantworten und Kontaktattribute löschen, die mit diesem Kontakt verbunden sind. Jegliche zielgerichtete Kommunikation und Personalisierung basierend auf den Daten dieses Kontakts gehen verloren.",
"first_name": "Vorname",
"last_name": "Nachname",
"no_responses_found": "Keine Antworten gefunden",
"not_provided": "Nicht angegeben",
"search_contact": "Kontakt suchen",
-2
View File
@@ -577,8 +577,6 @@
"contacts_table_refresh": "Refresh contacts",
"contacts_table_refresh_success": "Contacts refreshed successfully",
"delete_contact_confirmation": "This will delete all survey responses and contact attributes associated with this contact. Any targeting and personalization based on this contact's data will be lost.",
"first_name": "First Name",
"last_name": "Last Name",
"no_responses_found": "No responses found",
"not_provided": "Not provided",
"search_contact": "Search contact",
-2
View File
@@ -577,8 +577,6 @@
"contacts_table_refresh": "Rafraîchir les contacts",
"contacts_table_refresh_success": "Contacts rafraîchis avec succès",
"delete_contact_confirmation": "Cela supprimera toutes les réponses aux enquêtes et les attributs de contact associés à ce contact. Toute la personnalisation et le ciblage basés sur les données de ce contact seront perdus.",
"first_name": "Prénom",
"last_name": "Nom de famille",
"no_responses_found": "Aucune réponse trouvée",
"not_provided": "Non fourni",
"search_contact": "Rechercher un contact",
-2
View File
@@ -577,8 +577,6 @@
"contacts_table_refresh": "連絡先を更新",
"contacts_table_refresh_success": "連絡先を正常に更新しました",
"delete_contact_confirmation": "これにより、この連絡先に関連付けられているすべてのフォーム回答と連絡先属性が削除されます。この連絡先のデータに基づいたターゲティングとパーソナライゼーションはすべて失われます。",
"first_name": "名",
"last_name": "姓",
"no_responses_found": "回答が見つかりません",
"not_provided": "提供されていません",
"search_contact": "連絡先を検索",
-2
View File
@@ -577,8 +577,6 @@
"contacts_table_refresh": "Atualizar contatos",
"contacts_table_refresh_success": "Contatos atualizados com sucesso",
"delete_contact_confirmation": "Isso irá apagar todas as respostas da pesquisa e atributos de contato associados a este contato. Qualquer direcionamento e personalização baseados nos dados deste contato serão perdidos.",
"first_name": "Primeiro Nome",
"last_name": "Sobrenome",
"no_responses_found": "Nenhuma resposta encontrada",
"not_provided": "Não fornecido",
"search_contact": "Buscar contato",
-2
View File
@@ -577,8 +577,6 @@
"contacts_table_refresh": "Atualizar contactos",
"contacts_table_refresh_success": "Contactos atualizados com sucesso",
"delete_contact_confirmation": "Isto irá eliminar todas as respostas das pesquisas e os atributos de contato associados a este contato. Qualquer direcionamento e personalização baseados nos dados deste contato serão perdidos.",
"first_name": "Primeiro Nome",
"last_name": "Apelido",
"no_responses_found": "Nenhuma resposta encontrada",
"not_provided": "Não fornecido",
"search_contact": "Procurar contacto",
-2
View File
@@ -577,8 +577,6 @@
"contacts_table_refresh": "Reîmprospătare contacte",
"contacts_table_refresh_success": "Contactele au fost actualizate cu succes",
"delete_contact_confirmation": "Acest lucru va șterge toate răspunsurile la sondaj și atributele de contact asociate cu acest contact. Orice țintire și personalizare bazată pe datele acestui contact vor fi pierdute.",
"first_name": "Prenume",
"last_name": "Nume de familie",
"no_responses_found": "Nu s-au găsit răspunsuri",
"not_provided": "Nu a fost furnizat",
"search_contact": "Căutați contact",
-2
View File
@@ -577,8 +577,6 @@
"contacts_table_refresh": "重新整理聯絡人",
"contacts_table_refresh_success": "聯絡人已成功重新整理",
"delete_contact_confirmation": "這將刪除與此聯繫人相關的所有調查回應和聯繫屬性。任何基於此聯繫人數據的定位和個性化將會丟失。",
"first_name": "名字",
"last_name": "姓氏",
"no_responses_found": "找不到回應",
"not_provided": "未提供",
"search_contact": "搜尋聯絡人",
@@ -15,7 +15,7 @@ vi.mock("@react-email/components", () => ({
}));
// Mock dependencies
vi.mock("@/lib/storage/utils", () => ({
vi.mock("@/modules/storage/utils", () => ({
getOriginalFileNameFromUrl: (url: string) => {
// Extract filename from the URL for testing purposes
const parts = url.split("/");
+1 -1
View File
@@ -2,6 +2,7 @@ import {
isAllowedFileExtension,
isValidFileTypeForExtension,
isValidImageFile,
sanitizeFileName,
validateFileUploads,
validateSingleFile,
} from "@/modules/storage/utils";
@@ -10,7 +11,6 @@ import { StorageErrorCode } from "@formbricks/storage";
import { TResponseData } from "@formbricks/types/responses";
import { ZAllowedFileExtension } from "@formbricks/types/storage";
import { TSurveyQuestion } from "@formbricks/types/surveys/types";
import { sanitizeFileName } from "./utils";
// Mock the getOriginalFileNameFromUrl function
const mockGetOriginalFileNameFromUrl = vi.hoisted(() => vi.fn());
+1 -1
View File
@@ -45,7 +45,7 @@ export const sanitizeFileName = (rawFileName: string): string => {
// Remove control chars and characters problematic in S3 form fields or URLs
// Disallow: # <> : " | ? * ` ' and control whitespace
name = name.replace(/[\u0000-\u001F#<>:"|?*`'\n\r\t]/g, "");
name = name.replace(/[\u0000-\u001F#<>:"|?*`']/g, "");
// Collapse and trim whitespace
name = name.replace(/\s+/g, " ").trim();
+6 -2
View File
@@ -154,14 +154,18 @@ describe("ApiClient", () => {
});
test("throws an error if fetch for signing fails", async () => {
vi.mocked(global.fetch).mockResolvedValueOnce({ ok: false, status: 400 } as unknown as Response);
vi.mocked(global.fetch).mockResolvedValueOnce({
ok: false,
status: 400,
json: async () => ({ details: { fileName: "Invalid file name" } }),
} as unknown as Response);
await expect(() =>
client.uploadFile({
base64: "data:image/jpeg;base64,abcd",
name: "test.jpg",
type: "image/jpeg",
})
).rejects.toThrow("Upload failed with status: 400");
).rejects.toThrow("Invalid file name");
});
test("throws an error if actual upload fails", async () => {
+7 -3
View File
@@ -92,10 +92,14 @@ export class ApiClient {
if (!response.ok) {
if (response.status === 400) {
const err = new Error("Invalid file name");
err.name = "InvalidFileNameError";
throw err;
const json = (await response.json()) as ApiErrorResponse;
if (json.details?.fileName) {
const err = new Error("Invalid file name");
err.name = "InvalidFileNameError";
throw err;
}
}
throw new Error(`Upload failed with status: ${String(response.status)}`);
}