mirror of
https://github.com/Portabase/portabase.git
synced 2026-07-14 11:16:13 +02:00
migration
This commit is contained in:
+78
-27
@@ -1,43 +1,94 @@
|
||||
"use server"
|
||||
import {prisma} from "@/prisma";
|
||||
"use server";
|
||||
|
||||
import { db } from "@/db";
|
||||
import { setting as drizzleSetting } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
import nodemailer from "nodemailer";
|
||||
|
||||
type Payload = {
|
||||
to: string;
|
||||
from: string;
|
||||
subject: string;
|
||||
html: any
|
||||
html: any;
|
||||
};
|
||||
|
||||
type Server = {
|
||||
host: string;
|
||||
port: number;
|
||||
user: string;
|
||||
pass: string;
|
||||
from: string;
|
||||
};
|
||||
|
||||
type EmailCustomProps = {
|
||||
data: Payload;
|
||||
server: Server;
|
||||
};
|
||||
|
||||
type EmailMassProps = {
|
||||
data: Payload;
|
||||
servers: Server[];
|
||||
};
|
||||
|
||||
export const sendEmail = async (data: Payload) => {
|
||||
const settings = await db
|
||||
.select()
|
||||
.from(drizzleSetting)
|
||||
.where(eq(drizzleSetting.name, "system"))
|
||||
.then((res) => res[0]);
|
||||
|
||||
const settings = await prisma.settings.findUnique({
|
||||
where: {
|
||||
name: "system"
|
||||
}
|
||||
})
|
||||
if (!settings) {
|
||||
throw new Error("SMTP system settings not found.");
|
||||
}
|
||||
|
||||
const smtpSettings = {
|
||||
host: settings.smtpHost,
|
||||
port: parseInt(settings.smtpPort),
|
||||
auth: {
|
||||
user: settings.smtpUser,
|
||||
pass: settings.smtpPassword,
|
||||
},
|
||||
};
|
||||
|
||||
// Create a transporter object using nodemailer
|
||||
const transporter = nodemailer.createTransport({
|
||||
...smtpSettings
|
||||
pool: true,
|
||||
host: settings.smtpHost ?? "",
|
||||
port: parseInt(settings.smtpPort ?? "587"),
|
||||
secure: true,
|
||||
auth: {
|
||||
user: settings.smtpUser ?? "",
|
||||
pass: settings.smtpPassword ?? "",
|
||||
},
|
||||
});
|
||||
|
||||
// Set up email options
|
||||
const mailOptions = {
|
||||
...data
|
||||
};
|
||||
|
||||
return await transporter.sendMail({
|
||||
from: settings.smtpFrom,
|
||||
...mailOptions,
|
||||
...data,
|
||||
from: settings.smtpFrom ?? undefined,
|
||||
});
|
||||
};
|
||||
|
||||
export const sendCustomEmail = async (data: EmailCustomProps) => {
|
||||
const transporter = nodemailer.createTransport({
|
||||
secure: true,
|
||||
replyTo: data.server.user,
|
||||
host: data.server.host,
|
||||
port: data.server.port,
|
||||
auth: {
|
||||
user: data.server.user,
|
||||
pass: data.server.pass,
|
||||
},
|
||||
});
|
||||
|
||||
};
|
||||
return await transporter.sendMail({
|
||||
...data.data,
|
||||
});
|
||||
};
|
||||
|
||||
export const sendMassEmail = async (data: EmailMassProps) => {
|
||||
for (const server of data.servers) {
|
||||
const transporter = nodemailer.createTransport({
|
||||
secure: true,
|
||||
host: server.host,
|
||||
port: server.port,
|
||||
auth: {
|
||||
user: server.user,
|
||||
pass: server.pass,
|
||||
},
|
||||
});
|
||||
|
||||
return await transporter.sendMail({
|
||||
...data.data,
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import {env} from "@/env.mjs";
|
||||
import { env } from "@/env.mjs";
|
||||
|
||||
export const getServerUrl = () => {
|
||||
if (typeof window !== 'undefined') {
|
||||
if (typeof window !== "undefined") {
|
||||
return window.location.origin;
|
||||
}
|
||||
if(env.NODE_ENV === 'development') {
|
||||
return `http://${env.NEXT_PUBLIC_DOMAIN_NAME}`;
|
||||
if (env.NODE_ENV === "development") {
|
||||
return `http://${env.NEXT_PUBLIC_PROJECT_URL}`;
|
||||
}
|
||||
return `https://${env.NEXT_PUBLIC_DOMAIN_NAME}`;
|
||||
}
|
||||
return `https://${env.NEXT_PUBLIC_PROJECT_URL}`;
|
||||
};
|
||||
|
||||
+33
-55
@@ -1,25 +1,24 @@
|
||||
import {prisma} from "@/prisma";
|
||||
import {env} from "@/env.mjs";
|
||||
|
||||
import { env } from "@/env.mjs";
|
||||
import { db } from "@/db";
|
||||
import { setting, organization } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
export function init() {
|
||||
consoleAscii()
|
||||
console.log("====Init Functions====")
|
||||
consoleAscii();
|
||||
console.log("====Init Functions====");
|
||||
|
||||
createDefaultOrganization().then(() => {
|
||||
})
|
||||
createDefaultOrganization().then(() => {});
|
||||
|
||||
createSettingsIfNotExist()
|
||||
.then(() => {
|
||||
console.log('====Initialization completed====');
|
||||
console.log("====Initialization completed====");
|
||||
})
|
||||
.catch((err) => {
|
||||
console.error('Error during initialization:', err);
|
||||
console.error("Error during initialization:", err);
|
||||
});
|
||||
}
|
||||
|
||||
async function createSettingsIfNotExist() {
|
||||
|
||||
const configSettings = {
|
||||
name: "system",
|
||||
smtpPassword: env.SMTP_PASSWORD ?? null,
|
||||
@@ -31,63 +30,42 @@ async function createSettingsIfNotExist() {
|
||||
s3AccessKeyId: env.S3_ACCESS_KEY ?? null,
|
||||
s3SecretAccessKey: env.S3_SECRET_KEY ?? null,
|
||||
S3BucketName: env.S3_BUCKET_NAME ?? null,
|
||||
}
|
||||
};
|
||||
|
||||
const [existing] = await db.select().from(setting).where(eq(setting.name, "system")).limit(1);
|
||||
|
||||
const settings = await prisma.settings.findUnique({
|
||||
where: {
|
||||
name: "system",
|
||||
}
|
||||
})
|
||||
if (!settings) {
|
||||
console.log("====Init Setting : Create ====")
|
||||
await prisma.settings.create({
|
||||
data: {
|
||||
...configSettings
|
||||
}
|
||||
})
|
||||
if (!existing) {
|
||||
console.log("====Init Setting : Create ====");
|
||||
await db.insert(setting).values(configSettings);
|
||||
} else {
|
||||
console.log("====Init Setting : Update ====")
|
||||
await prisma.settings.update({
|
||||
where: {
|
||||
name: "system",
|
||||
},
|
||||
data: {
|
||||
...configSettings,
|
||||
}
|
||||
})
|
||||
console.log("====Init Setting : Update ====");
|
||||
await db.update(setting).set(configSettings).where(eq(setting.name, "system"));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
async function createDefaultOrganization() {
|
||||
|
||||
const defaultOrganizationConf = {
|
||||
slug: "default",
|
||||
name: "Default Organization",
|
||||
}
|
||||
createdAt: new Date(),
|
||||
};
|
||||
|
||||
const defaultOrganization = await prisma.organization.findUnique({
|
||||
where: {
|
||||
slug: "default",
|
||||
}
|
||||
})
|
||||
if (!defaultOrganization) {
|
||||
console.log("==== Creating default Organization... ====\n")
|
||||
await prisma.organization.create({
|
||||
data: {
|
||||
...defaultOrganizationConf
|
||||
}
|
||||
})
|
||||
const [existing] = await db.select().from(organization).where(eq(organization.slug, "default")).limit(1);
|
||||
|
||||
if (!existing) {
|
||||
console.log("==== Creating default Organization... ====\n");
|
||||
await db.insert(organization).values(defaultOrganizationConf);
|
||||
}
|
||||
}
|
||||
|
||||
function consoleAscii() {
|
||||
console.log("\n" +
|
||||
" ____ __ __ _____ \n" +
|
||||
" / __ \\ ____ _____ / /_ ____ _ / /_ ____ _ _____ ___ / ___/ ___ _____ _ __ ___ _____\n" +
|
||||
" / /_/ // __ \\ / ___// __// __ // __ \\ / __ // ___// _ \\ \\__ \\ / _ \\ / ___/| | / // _ \\ / ___/\n" +
|
||||
" / ____// /_/ // / / /_ / /_/ // /_/ // /_/ /(__ )/ __/ ___/ // __// / | |/ // __// / \n" +
|
||||
"/_/ \\____//_/ \\__/ \\__,_//_.___/ \\__,_//____/ \\___/ /____/ \\___//_/ |___/ \\___//_/ \n" +
|
||||
" \n")
|
||||
}
|
||||
console.log(
|
||||
"\n" +
|
||||
" ____ __ __ _____ \n" +
|
||||
" / __ \\ ____ _____ / /_ ____ _ / /_ ____ _ _____ ___ / ___/ ___ _____ _ __ ___ _____\n" +
|
||||
" / /_/ // __ \\ / ___// __// __ // __ \\ / __ // ___// _ \\ \\__ \\ / _ \\ / ___/| | / // _ \\ / ___/\n" +
|
||||
" / ____// /_/ // / / /_ / /_/ // /_/ // /_/ /(__ )/ __/ ___/ // __// / | |/ // __// / \n" +
|
||||
"/_/ \\____//_/ \\__/ \\__,_//_.___/ \\__,_//____/ \\___/ /____/ \\___//_/ |___/ \\___//_/ \n" +
|
||||
" \n"
|
||||
);
|
||||
}
|
||||
|
||||
+95
-102
@@ -1,122 +1,115 @@
|
||||
export const organizations = [
|
||||
{
|
||||
"id": "org-1a2b3c4e",
|
||||
"slug": "default",
|
||||
"name": "Default Organization",
|
||||
"createdAt": "2024-01-10T10:00:00.000Z",
|
||||
"projects": []
|
||||
slug: "default",
|
||||
name: "Default Organization",
|
||||
createdAt: "2024-01-10T10:00:00.000Z",
|
||||
projects: [],
|
||||
},
|
||||
{
|
||||
"id": "org-1a2b3c4d",
|
||||
"slug": "tech-corp",
|
||||
"name": "Tech Corp",
|
||||
"createdAt": "2024-01-10T10:00:00.000Z",
|
||||
"projects": []
|
||||
slug: "tech-corp",
|
||||
name: "Tech Corp",
|
||||
createdAt: "2024-01-10T10:00:00.000Z",
|
||||
projects: [],
|
||||
},
|
||||
{
|
||||
"id": "org-2e3f4g5h",
|
||||
"slug": "design-studio",
|
||||
"name": "Design Studio",
|
||||
"createdAt": "2023-09-15T15:45:00.000Z",
|
||||
"projects": []
|
||||
}
|
||||
]
|
||||
slug: "design-studio",
|
||||
name: "Design Studio",
|
||||
createdAt: "2023-09-15T15:45:00.000Z",
|
||||
projects: [],
|
||||
},
|
||||
];
|
||||
|
||||
export const projects = [
|
||||
{
|
||||
"id": "proj-1234abcd",
|
||||
"slug": "backend-system",
|
||||
"name": "Backend System",
|
||||
"createdAt": "2024-02-20T11:30:00.000Z",
|
||||
"organizationId": "org-1a2b3c4d",
|
||||
"databases": []
|
||||
}, {
|
||||
"id": "proj-5678efgh",
|
||||
"slug": "creative-suite",
|
||||
"name": "Creative Suite",
|
||||
"createdAt": "2023-10-10T08:20:00.000Z",
|
||||
"organizationId": "org-2e3f4g5h",
|
||||
"databases": []
|
||||
}
|
||||
]
|
||||
slug: "backend-system",
|
||||
name: "Backend System",
|
||||
createdAt: "2024-02-20T11:30:00.000Z",
|
||||
organizationId: "org-1a2b3c4d",
|
||||
databases: [],
|
||||
},
|
||||
{
|
||||
slug: "creative-suite",
|
||||
name: "Creative Suite",
|
||||
createdAt: "2023-10-10T08:20:00.000Z",
|
||||
organizationId: "org-2e3f4g5h",
|
||||
databases: [],
|
||||
},
|
||||
];
|
||||
|
||||
export const databases = [
|
||||
{
|
||||
"id": "c1a8e77c-eed9-4c8f-a9f7-90deabc3b78e",
|
||||
"name": "Main Production DB",
|
||||
"dbms": "postgresql",
|
||||
"generatedId": "prod-db-1",
|
||||
"description": "Primary database for production environment",
|
||||
"backupPolicy": "daily",
|
||||
"createdAt": "2024-11-01T12:00:00.000Z",
|
||||
"agentId": "agent-1234",
|
||||
"lastContact": "2024-11-28T08:30:00.000Z",
|
||||
"projectId": "proj-789",
|
||||
"backups": [],
|
||||
"restorations": []
|
||||
name: "Main Production DB",
|
||||
dbms: "postgresql",
|
||||
generatedId: "prod-db-1",
|
||||
description: "Primary database for production environment",
|
||||
backupPolicy: "daily",
|
||||
createdAt: "2024-11-01T12:00:00.000Z",
|
||||
agentId: "agent-1234",
|
||||
lastContact: "2024-11-28T08:30:00.000Z",
|
||||
projectId: "proj-789",
|
||||
backups: [],
|
||||
restorations: [],
|
||||
},
|
||||
{
|
||||
"id": "1e4f9265-5f10-4bd4-8e5c-3283746cfd7a",
|
||||
"name": "Staging DB",
|
||||
"dbms": "mysql",
|
||||
"generatedId": "staging-db-2",
|
||||
"description": "Database for testing and staging environment",
|
||||
"backupPolicy": "weekly",
|
||||
"createdAt": "2024-10-15T09:45:00.000Z",
|
||||
"agentId": "agent-5678",
|
||||
"lastContact": "2024-11-25T10:15:00.000Z",
|
||||
"projectId": null,
|
||||
"backups": [],
|
||||
"restorations": []
|
||||
name: "Staging DB",
|
||||
dbms: "mysql",
|
||||
generatedId: "staging-db-2",
|
||||
description: "Database for testing and staging environment",
|
||||
backupPolicy: "weekly",
|
||||
createdAt: "2024-10-15T09:45:00.000Z",
|
||||
agentId: "agent-5678",
|
||||
lastContact: "2024-11-25T10:15:00.000Z",
|
||||
projectId: null,
|
||||
backups: [],
|
||||
restorations: [],
|
||||
},
|
||||
{
|
||||
"id": "b6f92bd7-834b-41c1-b6b3-dc4214b1de08",
|
||||
"name": "Development DB",
|
||||
"dbms": "mongodb",
|
||||
"generatedId": "dev-db-3",
|
||||
"description": null,
|
||||
"backupPolicy": null,
|
||||
"createdAt": "2024-09-20T16:20:00.000Z",
|
||||
"agentId": "agent-9012",
|
||||
"lastContact": null,
|
||||
"projectId": "proj-456",
|
||||
"backups": [],
|
||||
"restorations": []
|
||||
}
|
||||
]
|
||||
name: "Development DB",
|
||||
dbms: "mongodb",
|
||||
generatedId: "dev-db-3",
|
||||
description: null,
|
||||
backupPolicy: null,
|
||||
createdAt: "2024-09-20T16:20:00.000Z",
|
||||
agentId: "agent-9012",
|
||||
lastContact: null,
|
||||
projectId: "proj-456",
|
||||
backups: [],
|
||||
restorations: [],
|
||||
},
|
||||
];
|
||||
|
||||
export const backups = [
|
||||
{'id': 'backup-1', 'createdAt': '2023-11-27T11:26:54.870914Z', 'status': 'pending'},
|
||||
{'id': 'backup-2', 'createdAt': '2023-12-03T11:26:54.870927Z', 'status': 'failed'},
|
||||
{'id': 'backup-3', 'createdAt': '2023-12-12T11:26:54.870937Z', 'status': 'success'},
|
||||
{'id': 'backup-4', 'createdAt': '2023-11-23T11:26:54.870946Z', 'status': 'processing'},
|
||||
{'id': 'backup-5', 'createdAt': '2023-12-09T11:26:54.870955Z', 'status': 'pending'},
|
||||
{'id': 'backup-6', 'createdAt': '2023-11-29T11:26:54.870964Z', 'status': 'failed'},
|
||||
{'id': 'backup-7', 'createdAt': '2023-12-07T11:26:54.870973Z', 'status': 'success'},
|
||||
{'id': 'backup-8', 'createdAt': '2023-11-18T11:26:54.870982Z', 'status': 'processing'},
|
||||
{'id': 'backup-9', 'createdAt': '2023-12-01T11:26:54.870991Z', 'status': 'pending'},
|
||||
{'id': 'backup-10', 'createdAt': '2023-11-25T11:26:54.871000Z', 'status': 'failed'},
|
||||
{'id': 'backup-1', 'createdAt': '2023-11-27T11:26:54.870914Z', 'status': 'pending'},
|
||||
{'id': 'backup-2', 'createdAt': '2023-12-03T11:26:54.870927Z', 'status': 'failed'},
|
||||
{'id': 'backup-3', 'createdAt': '2023-12-12T11:26:54.870937Z', 'status': 'success'},
|
||||
{'id': 'backup-4', 'createdAt': '2023-11-23T11:26:54.870946Z', 'status': 'processing'},
|
||||
{'id': 'backup-5', 'createdAt': '2023-12-09T11:26:54.870955Z', 'status': 'pending'},
|
||||
{'id': 'backup-6', 'createdAt': '2023-11-29T11:26:54.870964Z', 'status': 'failed'},
|
||||
{'id': 'backup-7', 'createdAt': '2023-12-07T11:26:54.870973Z', 'status': 'success'},
|
||||
{'id': 'backup-8', 'createdAt': '2023-11-18T11:26:54.870982Z', 'status': 'processing'},
|
||||
{'id': 'backup-9', 'createdAt': '2023-12-01T11:26:54.870991Z', 'status': 'pending'},
|
||||
{'id': 'backup-11', 'createdAt': '2023-11-25T11:26:54.871000Z', 'status': 'failed'}
|
||||
]
|
||||
{ createdAt: "2023-11-27T11:26:54.870914Z", status: "pending" },
|
||||
{ createdAt: "2023-12-03T11:26:54.870927Z", status: "failed" },
|
||||
{ createdAt: "2023-12-12T11:26:54.870937Z", status: "success" },
|
||||
{ createdAt: "2023-11-23T11:26:54.870946Z", status: "processing" },
|
||||
{ createdAt: "2023-12-09T11:26:54.870955Z", status: "pending" },
|
||||
{ createdAt: "2023-11-29T11:26:54.870964Z", status: "failed" },
|
||||
{ createdAt: "2023-12-07T11:26:54.870973Z", status: "success" },
|
||||
{ createdAt: "2023-11-18T11:26:54.870982Z", status: "processing" },
|
||||
{ createdAt: "2023-12-01T11:26:54.870991Z", status: "pending" },
|
||||
{ createdAt: "2023-11-25T11:26:54.871000Z", status: "failed" },
|
||||
{ createdAt: "2023-11-27T11:26:54.870914Z", status: "pending" },
|
||||
{ createdAt: "2023-12-03T11:26:54.870927Z", status: "failed" },
|
||||
{ createdAt: "2023-12-12T11:26:54.870937Z", status: "success" },
|
||||
{ createdAt: "2023-11-23T11:26:54.870946Z", status: "processing" },
|
||||
{ createdAt: "2023-12-09T11:26:54.870955Z", status: "pending" },
|
||||
{ createdAt: "2023-11-29T11:26:54.870964Z", status: "failed" },
|
||||
{ createdAt: "2023-12-07T11:26:54.870973Z", status: "success" },
|
||||
{ createdAt: "2023-11-18T11:26:54.870982Z", status: "processing" },
|
||||
{ createdAt: "2023-12-01T11:26:54.870991Z", status: "pending" },
|
||||
{ createdAt: "2023-11-25T11:26:54.871000Z", status: "failed" },
|
||||
];
|
||||
|
||||
export const restorations = [
|
||||
{'id': 'restore-1', 'backupId': 'backup-1', 'createdAt': '2023-11-27T11:26:54.870914Z', 'status': 'pending'},
|
||||
{'id': 'restore-2', 'backupId': 'backup-2', 'createdAt': '2023-12-03T11:26:54.870927Z', 'status': 'failed'},
|
||||
{'id': 'restore-3', 'backupId': 'backup-3', 'createdAt': '2023-12-12T11:26:54.870937Z', 'status': 'success'},
|
||||
{'id': 'restore-4', 'backupId': 'backup-4', 'createdAt': '2023-11-23T11:26:54.870946Z', 'status': 'processing'},
|
||||
{'id': 'restore-5', 'backupId': 'backup-5', 'createdAt': '2023-12-09T11:26:54.870955Z', 'status': 'pending'},
|
||||
{'id': 'restore-6', 'backupId': 'backup-6', 'createdAt': '2023-11-29T11:26:54.870964Z', 'status': 'failed'},
|
||||
{'id': 'restore-7', 'backupId': 'backup-7', 'createdAt': '2023-12-07T11:26:54.870973Z', 'status': 'success'},
|
||||
{'id': 'restore-8', 'backupId': 'backup-8', 'createdAt': '2023-11-18T11:26:54.870982Z', 'status': 'processing'},
|
||||
{'id': 'restore-9', 'backupId': 'backup-9', 'createdAt': '2023-12-01T11:26:54.870991Z', 'status': 'pending'},
|
||||
{'id': 'restore-10', 'backupId': 'backup-10', 'createdAt': '2023-11-25T11:26:54.871000Z', 'status': 'failed'}
|
||||
]
|
||||
{ backupId: "backup-1", createdAt: "2023-11-27T11:26:54.870914Z", status: "pending" },
|
||||
{ backupId: "backup-2", createdAt: "2023-12-03T11:26:54.870927Z", status: "failed" },
|
||||
{ backupId: "backup-3", createdAt: "2023-12-12T11:26:54.870937Z", status: "success" },
|
||||
{ backupId: "backup-4", createdAt: "2023-11-23T11:26:54.870946Z", status: "processing" },
|
||||
{ backupId: "backup-5", createdAt: "2023-12-09T11:26:54.870955Z", status: "pending" },
|
||||
{ backupId: "backup-6", createdAt: "2023-11-29T11:26:54.870964Z", status: "failed" },
|
||||
{ backupId: "backup-7", createdAt: "2023-12-07T11:26:54.870973Z", status: "success" },
|
||||
{ backupId: "backup-8", createdAt: "2023-11-18T11:26:54.870982Z", status: "processing" },
|
||||
{ backupId: "backup-9", createdAt: "2023-12-01T11:26:54.870991Z", status: "pending" },
|
||||
{ backupId: "backup-10", createdAt: "2023-11-25T11:26:54.871000Z", status: "failed" },
|
||||
];
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
export async function hashPassword(password: string): Promise<string> {
|
||||
const argon2 = require('argon2');
|
||||
return await argon2.hash(password);
|
||||
}
|
||||
|
||||
//Do not delete
|
||||
// export async function saltAndHashPassword(password: string) {
|
||||
// // Generate a salt and hash the password
|
||||
// const salt = await bcrypt.genSalt(10);
|
||||
// const hashedPassword = await bcrypt.hash(password, salt);
|
||||
//
|
||||
// // Return the hashed password
|
||||
// return hashedPassword;
|
||||
// }
|
||||
@@ -1,7 +1,9 @@
|
||||
import * as Minio from 'minio'
|
||||
import {env} from "@/env.mjs";
|
||||
import * as Minio from "minio";
|
||||
import { env } from "@/env.mjs";
|
||||
import internal from "node:stream";
|
||||
import {prisma} from "@/prisma";
|
||||
import { db } from "@/db";
|
||||
import { setting as drizzleSetting } from "@/db/schema";
|
||||
import { eq } from "drizzle-orm";
|
||||
|
||||
// const settings = await prisma.settings.findUnique({
|
||||
// where:{
|
||||
@@ -9,7 +11,6 @@ import {prisma} from "@/prisma";
|
||||
// }
|
||||
// })
|
||||
|
||||
|
||||
// Create a new Minio client with the S3 endpoint, access key, and secret key
|
||||
// export const s3Client = env.NODE_ENV === "production" ?
|
||||
// new Minio.Client({
|
||||
@@ -36,52 +37,58 @@ import {prisma} from "@/prisma";
|
||||
// useSSL: env.S3_USE_SSL === 'true'
|
||||
// })
|
||||
|
||||
async function getS3Client() {
|
||||
const settings = await db
|
||||
.select()
|
||||
.from(drizzleSetting)
|
||||
.where(eq(drizzleSetting.name, "system"))
|
||||
.then((res) => res[0]);
|
||||
|
||||
async function gets3Client() {
|
||||
if (!settings) {
|
||||
throw new Error("S3 settings not found in database.");
|
||||
}
|
||||
|
||||
const settings = await prisma.settings.findUnique({
|
||||
where: {
|
||||
name: "system"
|
||||
}
|
||||
})
|
||||
const baseConfig = {
|
||||
endPoint: settings.s3EndPointUrl ?? "",
|
||||
accessKey: settings.s3AccessKeyId ?? "",
|
||||
secretKey: settings.s3SecretAccessKey ?? "",
|
||||
};
|
||||
|
||||
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'
|
||||
})
|
||||
return s3Client
|
||||
const s3Client =
|
||||
env.NODE_ENV === "production"
|
||||
? new Minio.Client({
|
||||
...baseConfig,
|
||||
})
|
||||
: new Minio.Client({
|
||||
...baseConfig,
|
||||
port: Number(env.S3_PORT ?? 0),
|
||||
useSSL: env.S3_USE_SSL === "true",
|
||||
});
|
||||
|
||||
return s3Client;
|
||||
}
|
||||
|
||||
export async function checkMinioAlive() {
|
||||
try {
|
||||
console.log("Check MinioAlive");
|
||||
const s3Client = await gets3Client()
|
||||
const s3Client = await getS3Client();
|
||||
// Try to list buckets to check connectivity
|
||||
const buckets = await s3Client.listBuckets();
|
||||
console.log('MinIO is up and running. Buckets:', buckets);
|
||||
return {message: true}
|
||||
console.log("MinIO is up and running. Buckets:", buckets);
|
||||
return { message: true };
|
||||
} catch (error) {
|
||||
console.error('Error connecting to MinIO:', error);
|
||||
return {error: error}
|
||||
|
||||
console.error("Error connecting to MinIO:", error);
|
||||
return { error: error };
|
||||
}
|
||||
}
|
||||
|
||||
export async function createBucketIfNotExists(bucketName: string) {
|
||||
const s3Client = await gets3Client()
|
||||
const s3Client = await getS3Client();
|
||||
|
||||
const bucketExists = await s3Client.bucketExists(bucketName)
|
||||
const bucketExists = await s3Client.bucketExists(bucketName);
|
||||
if (!bucketExists) {
|
||||
console.log(`Creating bucket ${bucketName}`);
|
||||
await s3Client.makeBucket(bucketName)
|
||||
await s3Client.makeBucket(bucketName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,36 +98,28 @@ export async function createBucketIfNotExists(bucketName: string) {
|
||||
* @param fileName name of the file
|
||||
* @param file file to save
|
||||
*/
|
||||
export async function saveFileInBucket({
|
||||
bucketName,
|
||||
fileName,
|
||||
file,
|
||||
}: {
|
||||
bucketName: string
|
||||
fileName: string
|
||||
file: Buffer | internal.Readable
|
||||
}) {
|
||||
export async function saveFileInBucket({ bucketName, fileName, file }: { bucketName: string; fileName: string; file: Buffer | internal.Readable }) {
|
||||
// Check if Minio is Alive
|
||||
await checkMinioAlive()
|
||||
await checkMinioAlive();
|
||||
// Create bucket if it doesn't exist
|
||||
await createBucketIfNotExists(bucketName)
|
||||
await createBucketIfNotExists(bucketName);
|
||||
// check if file exists - optional.
|
||||
// Without this check, the file will be overwritten if it exists
|
||||
const fileExists = await checkFileExistsInBucket({
|
||||
bucketName,
|
||||
fileName,
|
||||
})
|
||||
});
|
||||
|
||||
console.log('File exists:', fileExists);
|
||||
console.log("File exists:", fileExists);
|
||||
|
||||
if (fileExists) {
|
||||
throw new Error('File already exists')
|
||||
throw new Error("File already exists");
|
||||
}
|
||||
const s3Client = await gets3Client()
|
||||
const s3Client = await getS3Client();
|
||||
|
||||
// Upload image to S3 bucket
|
||||
const result = await s3Client.putObject(bucketName, fileName, file)
|
||||
return result
|
||||
const result = await s3Client.putObject(bucketName, fileName, file);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,15 +128,15 @@ export async function saveFileInBucket({
|
||||
* @param fileName name of the file
|
||||
* @returns true if file exists, false if not
|
||||
*/
|
||||
export async function checkFileExistsInBucket({bucketName, fileName}: { bucketName: string; fileName: string }) {
|
||||
const s3Client = await gets3Client()
|
||||
export async function checkFileExistsInBucket({ bucketName, fileName }: { bucketName: string; fileName: string }) {
|
||||
const s3Client = await getS3Client();
|
||||
|
||||
try {
|
||||
await s3Client.statObject(bucketName, fileName)
|
||||
await s3Client.statObject(bucketName, fileName);
|
||||
} catch (error) {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
return true
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,25 +145,24 @@ export async function checkFileExistsInBucket({bucketName, fileName}: { bucketNa
|
||||
* @returns promise with array of presigned urls
|
||||
*/
|
||||
export async function createPresignedUrlToUpload({
|
||||
bucketName,
|
||||
fileName,
|
||||
expiry = 60 * 60, // 1 hour
|
||||
}: {
|
||||
bucketName: string
|
||||
fileName: string
|
||||
expiry?: number
|
||||
bucketName,
|
||||
fileName,
|
||||
expiry = 60 * 60, // 1 hour
|
||||
}: {
|
||||
bucketName: string;
|
||||
fileName: string;
|
||||
expiry?: number;
|
||||
}) {
|
||||
// Create bucket if it doesn't exist
|
||||
await createBucketIfNotExists(bucketName)
|
||||
const s3Client = await gets3Client()
|
||||
await createBucketIfNotExists(bucketName);
|
||||
const s3Client = await getS3Client();
|
||||
|
||||
return await s3Client.presignedPutObject(bucketName, fileName, expiry)
|
||||
return await s3Client.presignedPutObject(bucketName, fileName, expiry);
|
||||
}
|
||||
|
||||
|
||||
// Function to create a bucket and make it public
|
||||
export async function createPublicBucket({bucketName}: { bucketName: string }) {
|
||||
const s3Client = await gets3Client()
|
||||
export async function createPublicBucket({ bucketName }: { bucketName: string }) {
|
||||
const s3Client = await getS3Client();
|
||||
|
||||
try {
|
||||
// Check if the bucket already exists
|
||||
@@ -179,21 +177,21 @@ export async function createPublicBucket({bucketName}: { bucketName: string }) {
|
||||
|
||||
// Define a bucket policy for public access
|
||||
const policy = {
|
||||
Version: '2012-10-17',
|
||||
Version: "2012-10-17",
|
||||
Statement: [
|
||||
{
|
||||
Effect: 'Allow',
|
||||
Effect: "Allow",
|
||||
Principal: "*",
|
||||
Action: 's3:GetObject',
|
||||
Resource: `arn:aws:s3:::${bucketName}/*`
|
||||
}
|
||||
]
|
||||
Action: "s3:GetObject",
|
||||
Resource: `arn:aws:s3:::${bucketName}/*`,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
// Set the policy to the bucket
|
||||
await s3Client.setBucketPolicy(bucketName, JSON.stringify(policy));
|
||||
console.log(`Bucket ${bucketName} is now public.`);
|
||||
} catch (error) {
|
||||
console.error('Error creating bucket:', error);
|
||||
console.error("Error creating bucket:", error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
|
||||
const uuidv4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
|
||||
|
||||
export function isUuidv4(value: string): value is string {
|
||||
return uuidv4Regex.test(value);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user