mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-27 23:49:51 -05:00
fixes
This commit is contained in:
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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": "連絡先を検索",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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("/");
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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 () => {
|
||||
|
||||
@@ -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)}`);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user