mirror of
https://github.com/formbricks/formbricks.git
synced 2026-05-08 06:41:45 -05:00
fix: uploads (#1449)
Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
This commit is contained in:
@@ -1,8 +1,5 @@
|
||||
import { env } from "@/env.mjs";
|
||||
import { responses } from "@/app/lib/api/response";
|
||||
import { WEBAPP_URL } from "@formbricks/lib/constants";
|
||||
import { getSignedUrlForS3Upload } from "@formbricks/lib/storage/service";
|
||||
import { generateLocalSignedUrl } from "@formbricks/lib/crypto";
|
||||
import { getUploadSignedUrl } from "@formbricks/lib/storage/service";
|
||||
|
||||
const uploadPrivateFile = async (
|
||||
fileName: string,
|
||||
@@ -13,40 +10,14 @@ const uploadPrivateFile = async (
|
||||
const accessType = "private"; // private files are only accessible by the user who has access to the environment
|
||||
// if s3 is not configured, we'll upload to a local folder named uploads
|
||||
|
||||
if (!env.S3_ACCESS_KEY || !env.S3_SECRET_KEY || !env.S3_REGION || !env.S3_BUCKET_NAME) {
|
||||
try {
|
||||
const { signature, timestamp, uuid } = generateLocalSignedUrl(fileName, environmentId, fileType);
|
||||
|
||||
return responses.successResponse({
|
||||
signedUrl: `${WEBAPP_URL}/api/v1/client/storage/local`,
|
||||
signingData: {
|
||||
signature,
|
||||
timestamp,
|
||||
uuid,
|
||||
},
|
||||
fileUrl: new URL(`${WEBAPP_URL}/storage/${environmentId}/${accessType}/${fileName}`).href,
|
||||
});
|
||||
} catch (err) {
|
||||
return responses.internalServerErrorResponse(err.message);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const signedUrl = await getSignedUrlForS3Upload(
|
||||
fileName,
|
||||
fileType,
|
||||
accessType,
|
||||
environmentId,
|
||||
false,
|
||||
plan
|
||||
);
|
||||
const signedUrlResponse = await getUploadSignedUrl(fileName, environmentId, fileType, accessType, plan);
|
||||
|
||||
return responses.successResponse({
|
||||
signedUrl,
|
||||
fileUrl: new URL(`${WEBAPP_URL}/storage/${environmentId}/${accessType}/${fileName}`).href,
|
||||
...signedUrlResponse,
|
||||
});
|
||||
} catch (err) {
|
||||
return responses.internalServerErrorResponse(err.message);
|
||||
return responses.internalServerErrorResponse("Internal server error");
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1,7 +1,4 @@
|
||||
import { env } from "@/env.mjs";
|
||||
import { getSignedUrlForS3Upload } from "@formbricks/lib/storage/service";
|
||||
import { WEBAPP_URL } from "@formbricks/lib/constants";
|
||||
import { generateLocalSignedUrl } from "@formbricks/lib/crypto";
|
||||
import { getUploadSignedUrl } from "@formbricks/lib/storage/service";
|
||||
import { responses } from "@/app/lib/api/response";
|
||||
|
||||
const getSignedUrlForPublicFile = async (fileName: string, environmentId: string, fileType: string) => {
|
||||
@@ -9,41 +6,11 @@ const getSignedUrlForPublicFile = async (fileName: string, environmentId: string
|
||||
|
||||
// if s3 is not configured, we'll upload to a local folder named uploads
|
||||
|
||||
if (!env.S3_ACCESS_KEY || !env.S3_SECRET_KEY || !env.S3_REGION || !env.S3_BUCKET_NAME) {
|
||||
try {
|
||||
const { signature, timestamp, uuid } = generateLocalSignedUrl(fileName, environmentId, fileType);
|
||||
|
||||
return responses.successResponse({
|
||||
signedUrl: new URL(`${WEBAPP_URL}/api/v1/management/storage/local`).href,
|
||||
signingData: {
|
||||
signature,
|
||||
timestamp,
|
||||
uuid,
|
||||
},
|
||||
fileUrl: new URL(`${WEBAPP_URL}/storage/${environmentId}/${accessType}/${fileName}`).href,
|
||||
});
|
||||
} catch (err) {
|
||||
if (err.name === "FileTooLargeError") {
|
||||
return responses.badRequestResponse(err.message);
|
||||
}
|
||||
|
||||
return responses.internalServerErrorResponse("Internal server error");
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
const { presignedFields, signedUrl } = await getSignedUrlForS3Upload(
|
||||
fileName,
|
||||
fileType,
|
||||
accessType,
|
||||
environmentId,
|
||||
true
|
||||
);
|
||||
const signedUrlResponse = await getUploadSignedUrl(fileName, environmentId, fileType, accessType);
|
||||
|
||||
return responses.successResponse({
|
||||
signedUrl,
|
||||
presignedFields,
|
||||
fileUrl: new URL(`${WEBAPP_URL}/storage/${environmentId}/${accessType}/${fileName}`).href,
|
||||
...signedUrlResponse,
|
||||
});
|
||||
} catch (err) {
|
||||
return responses.internalServerErrorResponse("Internal server error");
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
import { responses } from "@/app/lib/api/response";
|
||||
import { storageCache } from "@formbricks/lib/storage/cache";
|
||||
import { deleteFile } from "@formbricks/lib/storage/service";
|
||||
import { TAccessType } from "@formbricks/types/storage";
|
||||
|
||||
export const handleDeleteFile = async (environmentId: string, accessType: TAccessType, fileName: string) => {
|
||||
try {
|
||||
const { message, success, code } = await deleteFile(environmentId, accessType, fileName);
|
||||
|
||||
if (success) {
|
||||
// revalidate cache
|
||||
storageCache.revalidate({ fileKey: `${environmentId}/${accessType}/${fileName}` });
|
||||
return responses.successResponse(message);
|
||||
}
|
||||
|
||||
if (code === 404) {
|
||||
return responses.notFoundResponse("File", "File not found");
|
||||
}
|
||||
|
||||
return responses.internalServerErrorResponse(message);
|
||||
} catch (err) {
|
||||
return responses.internalServerErrorResponse("Something went wrong");
|
||||
}
|
||||
};
|
||||
@@ -1,14 +1,14 @@
|
||||
import { env } from "@/env.mjs";
|
||||
import { responses } from "@/app/lib/api/response";
|
||||
import { UPLOADS_DIR } from "@formbricks/lib/constants";
|
||||
import { getFileFromLocalStorage, getFileFromS3 } from "@formbricks/lib/storage/service";
|
||||
import { getLocalFile, getS3File } from "@formbricks/lib/storage/service";
|
||||
import { notFound } from "next/navigation";
|
||||
import path from "path";
|
||||
|
||||
const getFile = async (environmentId: string, accessType: string, fileName: string) => {
|
||||
if (!env.S3_ACCESS_KEY || !env.S3_SECRET_KEY || !env.S3_REGION || !env.S3_BUCKET_NAME) {
|
||||
try {
|
||||
const { fileBuffer, metaData } = await getFileFromLocalStorage(
|
||||
const { fileBuffer, metaData } = await getLocalFile(
|
||||
path.join(UPLOADS_DIR, environmentId, accessType, fileName)
|
||||
);
|
||||
|
||||
@@ -24,7 +24,7 @@ const getFile = async (environmentId: string, accessType: string, fileName: stri
|
||||
}
|
||||
|
||||
try {
|
||||
const signedUrl = await getFileFromS3(`${environmentId}/${accessType}/${fileName}`);
|
||||
const signedUrl = await getS3File(`${environmentId}/${accessType}/${fileName}`);
|
||||
|
||||
return new Response(null, {
|
||||
status: 302,
|
||||
|
||||
@@ -6,6 +6,7 @@ import { ZStorageRetrievalParams } from "@formbricks/types/storage";
|
||||
import { getServerSession } from "next-auth";
|
||||
import { NextRequest } from "next/server";
|
||||
import getFile from "./lib/getFile";
|
||||
import { handleDeleteFile } from "@/app/storage/[environmentId]/[accessType]/[fileName]/lib/deleteFile";
|
||||
|
||||
export async function GET(
|
||||
_: NextRequest,
|
||||
@@ -43,3 +44,44 @@ export async function GET(
|
||||
|
||||
return await getFile(environmentId, accessType, fileName);
|
||||
}
|
||||
|
||||
export async function DELETE(_: NextRequest, { params }: { params: { fileName: string } }) {
|
||||
if (!params.fileName) {
|
||||
return responses.badRequestResponse("Fields are missing or incorrectly formatted", {
|
||||
fileName: "fileName is required",
|
||||
});
|
||||
}
|
||||
|
||||
const [environmentId, accessType, file] = params.fileName.split("/");
|
||||
|
||||
const paramValidation = ZStorageRetrievalParams.safeParse({ fileName: file, environmentId, accessType });
|
||||
|
||||
if (!paramValidation.success) {
|
||||
return responses.badRequestResponse(
|
||||
"Fields are missing or incorrectly formatted",
|
||||
transformErrorToDetails(paramValidation.error),
|
||||
true
|
||||
);
|
||||
}
|
||||
// check if user is authenticated
|
||||
|
||||
const session = await getServerSession(authOptions);
|
||||
|
||||
if (!session || !session.user) {
|
||||
return responses.notAuthenticatedResponse();
|
||||
}
|
||||
|
||||
// check if the user has access to the environment
|
||||
|
||||
const isUserAuthorized = await hasUserEnvironmentAccess(session.user.id, environmentId);
|
||||
|
||||
if (!isUserAuthorized) {
|
||||
return responses.unauthorizedResponse();
|
||||
}
|
||||
|
||||
return await handleDeleteFile(
|
||||
paramValidation.data.environmentId,
|
||||
paramValidation.data.accessType,
|
||||
paramValidation.data.fileName
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user