fix(S3): add support for custom endpoint (#2049)

Co-authored-by: Matti Nannt <mail@matthiasnannt.com>
This commit is contained in:
Midka
2024-02-27 13:39:43 +02:00
committed by GitHub
parent 8064e1ecf6
commit b1c2f90feb
4 changed files with 43 additions and 4 deletions
@@ -122,6 +122,11 @@ These variables can be provided at the runtime i.e. in your docker-compose file.
| NEXTAUTH_SECRET | Secret for NextAuth, used for session signing and encryption. | required | (Generated by the user) |
| ENCRYPTION_KEY | Secret for used by Formbricks for data encryption | required | (Generated by the user) |
| NEXTAUTH_URL | Location of the auth server. By default, this is the Formbricks docker instance itself. | required | `http://localhost:3000` |
| S3_ACCESS_KEY | Access key for S3. | optional (required if S3 is enabled) | |
| S3_SECRET_KEY | Secret key for S3. | optional (required if S3 is enabled) | |
| S3_REGION | Region for S3. | optional (required if S3 is enabled) | |
| S3_BUCKET | Bucket name for S3. | optional (required if S3 is enabled) | |
| S3_ENDPOINT | Endpoint for S3. | optional (required if S3 is enabled) | |
| PRIVACY_URL | URL for privacy policy. | optional | |
| TERMS_URL | URL for terms of service. | optional | |
| IMPRINT_URL | URL for imprint. | optional | |
@@ -155,7 +160,7 @@ These variables can be provided at the runtime i.e. in your docker-compose file.
| OIDC_CLIENT_ID | Client ID for Custom OpenID Connect Provider | optional (required if OIDC auth is enabled) | |
| OIDC_CLIENT_SECRET | Secret for Custom OpenID Connect Provider | optional (required if OIDC auth is enabled) | |
| OIDC_ISSUER | Issuer URL for Custom OpenID Connect Provider (should have `.well-known` configured at this) | optional (required if OIDC auth is enabled) | |
| OIDC_SIGNING_ALGORITHM | Signing Algorithm for Custom OpenID Connect Provider | optional | `RS256` |
| OIDC_SIGNING_ALGORITHM | Signing Algorithm for Custom OpenID Connect Provider | optional | `RS256` |
## Build-time Variables
@@ -200,9 +200,10 @@ export default async function handle(req: NextApiRequest, res: NextApiResponse)
href: "https://spark-framework.net",
},
{
"name": "Tiledesk",
"description": "The innovative open-source framework for developing LLM-enabled chatbots, Tiledesk empowers developers to create advanced, conversational AI agents.",
"href": "https://tiledesk.com"
name: "Tiledesk",
description:
"The innovative open-source framework for developing LLM-enabled chatbots, Tiledesk empowers developers to create advanced, conversational AI agents.",
href: "https://tiledesk.com",
},
{
name: "Tolgee",
+12
View File
@@ -2,6 +2,8 @@ import { CheckBadgeIcon } from "@heroicons/react/24/outline";
import { Metadata } from "next";
import { prisma } from "@formbricks/database";
import { IS_S3_CONFIGURED } from "@formbricks/lib/constants";
import { testS3Connection } from "@formbricks/lib/storage/service";
export const dynamic = "force-dynamic"; // no caching
@@ -24,8 +26,18 @@ const checkDatabaseConnection = async () => {
}
};
const checkS3Connection = async () => {
if (!IS_S3_CONFIGURED) {
// dont try connecting if not in use
return;
}
await testS3Connection();
};
export default async function HealthPage() {
await checkDatabaseConnection();
await checkS3Connection();
return (
<div className="mx-auto flex h-full max-w-xl flex-col items-center justify-center text-center">
+21
View File
@@ -2,6 +2,7 @@ import {
DeleteObjectCommand,
DeleteObjectsCommand,
GetObjectCommand,
ListBucketsCommand,
ListObjectsCommand,
PutObjectCommand,
S3Client,
@@ -49,6 +50,26 @@ export const getS3Client = () => {
return s3ClientInstance;
};
export const testS3Connection = async () => {
try {
const s3Client = getS3Client();
const cmd = new ListBucketsCommand({});
const result = await s3Client.send(cmd);
if (!result.Buckets) {
throw new Error("Access denied to any buckets");
}
const bucketNames = result.Buckets.map((b) => b.Name);
if (!bucketNames.includes(S3_BUCKET_NAME)) {
throw new Error("Access denied to bucket");
}
} catch (error) {
throw new Error(`S3: ${error}`);
}
};
const ensureDirectoryExists = async (dirPath: string) => {
try {
await access(dirPath);