mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
Working on the s3 feature.
This commit is contained in:
@@ -2,9 +2,17 @@ import path from "path";
|
|||||||
import fs from "fs/promises";
|
import fs from "fs/promises";
|
||||||
import { NextResponse } from "next/server";
|
import { NextResponse } from "next/server";
|
||||||
|
|
||||||
export async function GET({ params }: { params: Promise<{ fileName: string }> }) {
|
export async function GET(
|
||||||
|
request: Request,
|
||||||
|
{params}: { params: Promise<{ fileName: string }> }
|
||||||
|
) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const fileName = (await params).fileName;
|
const fileName = (await params).fileName;
|
||||||
|
|
||||||
|
|
||||||
|
console.log("fileName", fileName);
|
||||||
|
|
||||||
const filePath = path.join(process.cwd(), "private/uploads/images", fileName);
|
const filePath = path.join(process.cwd(), "private/uploads/images", fileName);
|
||||||
|
|
||||||
// Check if the file exists
|
// Check if the file exists
|
||||||
|
|||||||
@@ -53,16 +53,19 @@ services:
|
|||||||
# - db
|
# - db
|
||||||
|
|
||||||
s3:
|
s3:
|
||||||
|
container_name: s3-portabase-dev
|
||||||
image: docker.io/bitnami/minio:latest
|
image: docker.io/bitnami/minio:latest
|
||||||
ports:
|
ports:
|
||||||
- "9000:9000"
|
- "9000:9000"
|
||||||
- "9001:9001"
|
- "9001:9001"
|
||||||
volumes:
|
volumes:
|
||||||
- minio_data:/data
|
- minio_data:/data
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
- MINIO_ROOT_USER=${S3_ACCESS_KEY}
|
- MINIO_ROOT_USER=${S3_ACCESS_KEY}
|
||||||
- MINIO_ROOT_PASSWORD=${S3_SECRET_KEY}
|
- MINIO_ROOT_PASSWORD=${S3_SECRET_KEY}
|
||||||
- MINIO_DEFAULT_BUCKETS=${S3_BUCKET_NAME}
|
- MINIO_DEFAULT_BUCKETS=${S3_BUCKET_NAME}
|
||||||
|
- MINIO_BROWSER=on
|
||||||
|
|
||||||
volumes:
|
volumes:
|
||||||
postgres-data:
|
postgres-data:
|
||||||
|
|||||||
+31
-17
@@ -1,16 +1,19 @@
|
|||||||
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";
|
import {Alert, AlertDescription, AlertTitle} from "@/components/ui/alert";
|
||||||
import { Info, ShieldCheck } from "lucide-react";
|
import {Info, ShieldCheck} from "lucide-react";
|
||||||
import { Switch } from "@/components/ui/switch";
|
import {Switch} from "@/components/ui/switch";
|
||||||
import { Label } from "@/components/ui/label";
|
import {Label} from "@/components/ui/label";
|
||||||
import { StorageS3Form } from "@/components/wrappers/dashboard/admin/admin-storage-tab/storage-s3/storage-s3-form";
|
import {StorageS3Form} from "@/components/wrappers/dashboard/admin/admin-storage-tab/storage-s3/storage-s3-form";
|
||||||
import { useState } from "react";
|
import {useState} from "react";
|
||||||
import { ButtonWithLoading } from "@/components/wrappers/common/button/button-with-loading";
|
import {ButtonWithLoading} from "@/components/wrappers/common/button/button-with-loading";
|
||||||
import { useMutation } from "@tanstack/react-query";
|
import {useMutation} from "@tanstack/react-query";
|
||||||
import { checkConnexionToS3 } from "@/features/upload/public/upload.action";
|
import {checkConnexionToS3} from "@/features/upload/public/upload.action";
|
||||||
import { toast } from "sonner";
|
import {toast} from "sonner";
|
||||||
import { useRouter } from "next/navigation";
|
import {useRouter} from "next/navigation";
|
||||||
import { updateStorageSettingsAction } from "@/components/wrappers/dashboard/admin/admin-storage-tab/storage-s3/s3-form.action";
|
import {
|
||||||
|
updateStorageSettingsAction
|
||||||
|
} from "@/components/wrappers/dashboard/admin/admin-storage-tab/storage-s3/s3-form.action";
|
||||||
import {Setting} from "@/db/schema/00_setting";
|
import {Setting} from "@/db/schema/00_setting";
|
||||||
|
import {S3FormType} from "@/components/wrappers/dashboard/admin/admin-storage-tab/storage-s3/s3-form.schema";
|
||||||
|
|
||||||
export type SettingsStorageTabProps = {
|
export type SettingsStorageTabProps = {
|
||||||
settings: Setting;
|
settings: Setting;
|
||||||
@@ -33,7 +36,7 @@ export const SettingsStorageTab = (props: SettingsStorageTabProps) => {
|
|||||||
const [isSwitched, setIsSwitched] = useState<boolean>(props.settings.storage !== "local");
|
const [isSwitched, setIsSwitched] = useState<boolean>(props.settings.storage !== "local");
|
||||||
|
|
||||||
const updateMutation = useMutation({
|
const updateMutation = useMutation({
|
||||||
mutationFn: () => updateStorageSettingsAction({ name: "system", data: { storage: isSwitched ? "s3" : "local" } }),
|
mutationFn: () => updateStorageSettingsAction({name: "system", data: {storage: isSwitched ? "s3" : "local"}}),
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
toast.success(`Settings updated successfully.`);
|
toast.success(`Settings updated successfully.`);
|
||||||
router.refresh();
|
router.refresh();
|
||||||
@@ -48,14 +51,25 @@ export const SettingsStorageTab = (props: SettingsStorageTabProps) => {
|
|||||||
await updateMutation.mutateAsync();
|
await updateMutation.mutateAsync();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const extractS3FormValues = (settings: Setting): S3FormType | undefined => {
|
||||||
|
if (!settings.s3EndPointUrl) return undefined;
|
||||||
|
return {
|
||||||
|
s3EndPointUrl: settings.s3EndPointUrl,
|
||||||
|
s3AccessKeyId: settings.s3AccessKeyId!,
|
||||||
|
s3SecretAccessKey: settings.s3SecretAccessKey!,
|
||||||
|
S3BucketName: settings.S3BucketName!,
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col h-full py-4">
|
<div className="flex flex-col h-full py-4">
|
||||||
<h1>Settings for Portabase storage</h1>
|
<h1>Settings for Portabase storage</h1>
|
||||||
<Alert className="mt-3">
|
<Alert className="mt-3">
|
||||||
<Info className="h-4 w-4" />
|
<Info className="h-4 w-4"/>
|
||||||
<AlertTitle>Informations</AlertTitle>
|
<AlertTitle>Informations</AlertTitle>
|
||||||
<AlertDescription>
|
<AlertDescription>
|
||||||
Actually you can only store you data in one place : s3 compatible or in local. For exemple you cannot choose to store images in one place
|
Actually you can only store you data in one place : s3 compatible or in local. For exemple you
|
||||||
|
cannot choose to store images in one place
|
||||||
and .dump files in another.
|
and .dump files in another.
|
||||||
</AlertDescription>
|
</AlertDescription>
|
||||||
</Alert>
|
</Alert>
|
||||||
@@ -79,14 +93,14 @@ export const SettingsStorageTab = (props: SettingsStorageTabProps) => {
|
|||||||
onClick={async () => {
|
onClick={async () => {
|
||||||
await mutation.mutateAsync();
|
await mutation.mutateAsync();
|
||||||
}}
|
}}
|
||||||
icon={<ShieldCheck />}
|
icon={<ShieldCheck/>}
|
||||||
text="Test connexion"
|
text="Test connexion"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{isSwitched && (
|
{isSwitched && (
|
||||||
<div className="mt-5">
|
<div className="mt-5">
|
||||||
<StorageS3Form defaultValues={props.settings.s3EndPointUrl ? props.settings : null} />
|
<StorageS3Form defaultValues={extractS3FormValues(props.settings)}/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ export const AvatarWithUpload = (props: AvatarWithUploadProps) => {
|
|||||||
submitImage.mutate(file);
|
submitImage.mutate(file);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative ">
|
<div className="relative ">
|
||||||
<Avatar className="size-14 mr-3 ">
|
<Avatar className="size-14 mr-3 ">
|
||||||
|
|||||||
@@ -5,37 +5,6 @@ import {db} from "@/db";
|
|||||||
import * as drizzleDb from "@/db";
|
import * as drizzleDb from "@/db";
|
||||||
import {eq} from "drizzle-orm";
|
import {eq} from "drizzle-orm";
|
||||||
|
|
||||||
// const settings = await prisma.settings.findUnique({
|
|
||||||
// where:{
|
|
||||||
// name: "system"
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
// Create a new Minio client with the S3 endpoint, access key, and secret key
|
|
||||||
// export const s3Client = env.NODE_ENV === "production" ?
|
|
||||||
// new Minio.Client({
|
|
||||||
// endPoint: env.S3_ENDPOINT ?? "",
|
|
||||||
// accessKey: env.S3_ACCESS_KEY ?? "",
|
|
||||||
// secretKey: env.S3_SECRET_KEY ?? "",
|
|
||||||
// }) : new Minio.Client({
|
|
||||||
// endPoint: env.S3_ENDPOINT ?? "",
|
|
||||||
// port: Number(env.S3_PORT ?? 0),
|
|
||||||
// accessKey: env.S3_ACCESS_KEY ?? "",
|
|
||||||
// secretKey: env.S3_SECRET_KEY ?? "",
|
|
||||||
// useSSL: env.S3_USE_SSL === 'true'
|
|
||||||
// })
|
|
||||||
// export const s3Client = env.NODE_ENV === "production" ?
|
|
||||||
// new Minio.Client({
|
|
||||||
// endPoint: settings.s3EndPointUrl ?? "",
|
|
||||||
// accessKey: settings.s3AccessKeyId ?? "",
|
|
||||||
// secretKey: settings.s3SecretAccessKey ?? "",
|
|
||||||
// }) : new Minio.Client({
|
|
||||||
// endPoint: settings.s3EndPointUrl ?? "",
|
|
||||||
// port: Number(env.S3_PORT ?? 0),
|
|
||||||
// accessKey: settings.s3AccessKeyId ?? "",
|
|
||||||
// secretKey: settings.s3SecretAccessKey ?? "",
|
|
||||||
// useSSL: env.S3_USE_SSL === 'true'
|
|
||||||
// })
|
|
||||||
|
|
||||||
async function getS3Client() {
|
async function getS3Client() {
|
||||||
const settings = await db
|
const settings = await db
|
||||||
|
|||||||
Reference in New Issue
Block a user