Compare commits

..
19 changed files with 342 additions and 52 deletions
+6
View File
@@ -105,6 +105,9 @@ Installation steps in order to use it locally and work on some features improvem
- [ ] Add tests procedure
- [ ] Add Release File
- [ ] Security improvements
- [ ] Improve UX/UI
- [ ] Improve Workspace system
- [ ] Migrate to Drizzle ORM
- [ ] Multi locale support
- [ ] Multi db support
- [x] PostgreSQL
@@ -148,6 +151,9 @@ If you're using Semantic Versioning (SemVer) to version your Docker images, you
```major.minor.patch-rc.release-tag (e.g. 1.0.0-rc.1-dev)```
For zenstask
```zenstack generate```
<!-- LICENSE -->
## License
+1 -1
View File
@@ -12,7 +12,7 @@ export async function GET(
const expires = searchParams.get('expires');
const fileName = (await params).fileName
const privateLocalDir = "private/uploads/";
const privateLocalDir = "private/uploads/files/";
const filePath = path.join(privateLocalDir, fileName);
const crypto = require('crypto');
+34
View File
@@ -0,0 +1,34 @@
import path from "path";
import fs from "fs/promises";
import {NextResponse} from "next/server";
export async function GET(
request: Request,
{params}: { params: Promise<{ fileName: string }> }
) {
try {
const fileName = (await params).fileName
const filePath = path.join(process.cwd(), "private/uploads/images", fileName);
// Check if the file exists
try {
await fs.access(filePath); // Ensures the file exists
} catch {
return NextResponse.json({error: "File not found"}, {status: 404});
}
// Read the file
const fileContent = await fs.readFile(filePath); // Returns a Buffer
return new NextResponse(fileContent, {
headers: {
"Content-Disposition": `attachment; filename="${fileName}"`,
"Content-Type": "application/octet-stream", // Adjust MIME type as needed
},
});
} catch (error) {
console.error("Error reading file:", error);
return NextResponse.json({error: "Internal Server Error"}, {status: 500});
}
}
+32
View File
@@ -0,0 +1,32 @@
import {NextResponse} from "next/server";
export type BodyInit = {
initialize: boolean
}
export async function POST(
request: Request,
) {
try {
const body: BodyInit = await request.json();
console.log(body)
return NextResponse.json(
{
message: "Initialization successfully done!",
},
{ status: 200 }
);
} catch (error) {
console.error("Error in POST initialization:", error);
return NextResponse.json(
{ error: "Internal server error" },
{ status: 500 }
);
}
}
+3 -1
View File
@@ -21,7 +21,9 @@ export default function RootLayout({
}>) {
return (
<html lang="en" suppressHydrationWarning>
<body className={cn(inter.className, "h-full")}>
<body
className={cn(inter.className, "h-full")}
>
<Providers>
{children}
</Providers>
+3 -3
View File
@@ -45,9 +45,9 @@ services:
volumes:
- minio_data:/data
environment:
- MINIO_ROOT_USER=SoluceTechnologies
- MINIO_ROOT_PASSWORD=p18avkwHPDh9mk
- MINIO_DEFAULT_BUCKETS=statics
- MINIO_ROOT_USER=${S3_ACCESS_KEY}
- MINIO_ROOT_PASSWORD=${S3_SECRET_KEY}
- MINIO_DEFAULT_BUCKETS=${S3_BUCKET_NAME}
volumes:
+3 -3
View File
@@ -56,9 +56,9 @@ services:
volumes:
- minio_data:/data
environment:
- MINIO_ROOT_USER=SoluceTechnologies
- MINIO_ROOT_PASSWORD=p18avkwHPDh9mk
- MINIO_DEFAULT_BUCKETS=statics
- MINIO_ROOT_USER=${S3_ACCESS_KEY}
- MINIO_ROOT_PASSWORD=${S3_SECRET_KEY}
- MINIO_DEFAULT_BUCKETS=${S3_BUCKET_NAME}
+1
View File
@@ -76,6 +76,7 @@ COPY --from=builder /app/public ./public
RUN mkdir .next
RUN mkdir -p /app/private/uploads
RUN chown -R nextjs:nodejs /app/private
RUN chown -R nextjs:nodejs /app/public
RUN chown nextjs:nodejs .next
+2 -1
View File
@@ -6,7 +6,8 @@ echo " / /_/ / __ \/ ___/ __/ __ / __ \/ __ / ___/ _ \ "
echo " / ____/ /_/ / / / /_/ /_/ / /_/ / /_/ (__ ) __/ "
echo " /_/ \____/_/ \__/\__,_/_.___/\__,_/____/\___/ "
echo " "
echo " Community Edition "
echo " Community Edition v1.0.0 "
echo " "
npx prisma migrate deploy
+2 -2
View File
@@ -1,6 +1,6 @@
import {init} from "@/utils/init";
export async function register() {
init()
export function register() {
init();
}
+2
View File
@@ -41,7 +41,9 @@ function checkRouteExists(pathname) {
/^\/api\/agent\/[^/]+\/backup\/?$/,
/^\/api\/agent\/[^/]+\/restore\/?$/,
/^\/api\/files\/[^/]+\/?$/,
/^\/api\/images\/[^/]+\/?$/,
/^\/api\/events\/?$/,
/^\/api\/init\/?$/,
];
return routePatterns.some(pattern => pattern.test(pathname));
}
+1 -9
View File
@@ -3,21 +3,13 @@
const nextConfig = {
output: "standalone",
typescript: {
//TODO fix all type errors and remove 'ignoreBuildErrors'
// !! WARN !!
// Dangerously allow production builds to successfully complete even if
// your project has type errors.
// !! WARN !!
ignoreBuildErrors: true,
},
eslint: {
ignoreDuringBuilds: true,
},
// bundlePagesRouterDependencies: true,
compiler: {
removeConsole: {
exclude: ['error'],
},
removeConsole: process.env.NODE_ENV === 'production',
},
};
+1
View File
@@ -85,6 +85,7 @@
"devDependencies": {
"@types/eslint-plugin-tailwindcss": "^3",
"@types/node": "^20",
"@types/pg": "^8",
"@types/react": "npm:types-react@19.0.0-rc.1",
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.1",
"@zenstackhq/openapi": "^2.10.2",
+3 -3
View File
@@ -121,9 +121,9 @@ enum OrganizationRole {
model UserOrganization extends Base {
userId String
organizationId String
user User @relation(fields: [userId], references: [id])
organization Organization @relation(fields: [organizationId], references: [id])
role OrganizationRole
user User @relation(fields: [userId], references: [id])
organization Organization @relation(fields: [organizationId], references: [id])
role OrganizationRole
@@unique([userId, organizationId])
@@map("users_organisations")
+10 -1
View File
@@ -117,7 +117,16 @@ export const {handlers, auth: baseAuth, signIn, signOut} = NextAuth({
const defaultOrganization = await prisma.organization.findUnique({
where: {slug: "default"},
include: {users: {}}
include: {users: {
include:{
user: true
},
where:{
user: {
deleted: {not: true},
}
}
}}
});
const organizationRole = defaultOrganization.users.length > 0 ? "member" : "admin"
+1 -1
View File
@@ -5,7 +5,7 @@ import path from "path";
import * as fs from "node:fs";
import {getServerUrl} from "@/utils/get-server-url";
const privateLocalDir = "private/uploads/";
const privateLocalDir = "private/uploads/files/";
export async function uploadLocalPrivate(fileName: string, buffer: any) {
+11 -4
View File
@@ -10,6 +10,7 @@ import {checkMinioAlive, createPublicBucket, saveFileInBucket} from "@/utils/s3-
import {prisma} from "@/prisma";
import {UploadedObjectInfo} from "minio/src/internal/type";
import {Settings} from "@prisma/client";
import {getServerUrl} from "@/utils/get-server-url";
export const uploadImageAction = userAction
@@ -50,19 +51,25 @@ export const uploadImageAction = userAction
function getUrl(fileName:string, settings: Settings, bucketName: string):string {
if (env.NODE_ENV === "production") {
// url = `https://${env.S3_ENDPOINT}/${bucketName}/${fileName}`
return "url"
if(settings.storage === "s3"){
return `https://${env.S3_ENDPOINT}/${bucketName}/${fileName}`
}else if(settings.storage === "local"){
const url = getServerUrl()
return `${url}/api/images/${fileName}`
}
} else {
if(settings.storage === "s3"){
return `http://localhost:${env.S3_PORT}/${bucketName}/${fileName}`
}else if(settings.storage === "local"){
return `http://localhost:8887/uploads/${fileName}`
const url = getServerUrl()
return `${url}/api/images/${fileName}`
}
}
}
async function uploadLocal(fileName: string, buffer: any) {
const localDir = "public/uploads/"
const localDir = "private/uploads/images/"
try {
await mkdir(path.join(process.cwd(), localDir), { recursive: true });
return await writeFile(
-1
View File
@@ -1,7 +1,6 @@
import {PrismaClient} from '@prisma/client'
const prismaClientSingleton = () => {
return new PrismaClient()
}
+226 -22
View File
@@ -1089,6 +1089,18 @@ __metadata:
languageName: node
linkType: hard
"@prisma/adapter-pg@npm:^6.1.0":
version: 6.1.0
resolution: "@prisma/adapter-pg@npm:6.1.0"
dependencies:
"@prisma/driver-adapter-utils": "npm:6.1.0"
postgres-array: "npm:3.0.2"
peerDependencies:
pg: ^8.11.3
checksum: 10c0/12aea5b7044f64d8ac9c40a3811d8598e6344c4ec5a755259091a246ab2932ef60de65eacf66d8f70cc26465545a6b9b5a77d6410e7758c7b1d311f8fbddebba
languageName: node
linkType: hard
"@prisma/client@npm:^6.1.0":
version: 6.1.0
resolution: "@prisma/client@npm:6.1.0"
@@ -1108,6 +1120,15 @@ __metadata:
languageName: node
linkType: hard
"@prisma/driver-adapter-utils@npm:6.1.0":
version: 6.1.0
resolution: "@prisma/driver-adapter-utils@npm:6.1.0"
dependencies:
"@prisma/debug": "npm:6.1.0"
checksum: 10c0/1a7985c7520d9a07a4ba7c04682bbe1cdb4bb41b45c55e5f33b6ed6a2ebf7e9f06bcff591f0079662686447f82ac501a7bb8652f39fd54b03b7f9315f278e485
languageName: node
linkType: hard
"@prisma/engines-version@npm:6.1.0-21.11f085a2012c0f4778414c8db2651556ee0ef959":
version: 6.1.0-21.11f085a2012c0f4778414c8db2651556ee0ef959
resolution: "@prisma/engines-version@npm:6.1.0-21.11f085a2012c0f4778414c8db2651556ee0ef959"
@@ -2840,6 +2861,17 @@ __metadata:
languageName: node
linkType: hard
"@types/pg@npm:^8":
version: 8.11.10
resolution: "@types/pg@npm:8.11.10"
dependencies:
"@types/node": "npm:*"
pg-protocol: "npm:*"
pg-types: "npm:^4.0.1"
checksum: 10c0/c8800d0ab2c6424308e6c6b40c73f19583ee1aed758462bd07694844b0a551b5841442205a4ee05207b80109ba502f33f20241b1bd9b4902e713611fb9e08f6c
languageName: node
linkType: hard
"@types/react-dom@npm:types-react-dom@19.0.0-rc.1":
version: 19.0.0-rc.1
resolution: "types-react-dom@npm:19.0.0-rc.1"
@@ -7309,6 +7341,13 @@ __metadata:
languageName: node
linkType: hard
"obuf@npm:~1.1.2":
version: 1.1.2
resolution: "obuf@npm:1.1.2"
checksum: 10c0/520aaac7ea701618eacf000fc96ae458e20e13b0569845800fc582f81b386731ab22d55354b4915d58171db00e79cfcd09c1638c02f89577ef092b38c65b7d81
languageName: node
linkType: hard
"once@npm:^1.3.0, once@npm:^1.3.1, once@npm:^1.4.0":
version: 1.4.0
resolution: "once@npm:1.4.0"
@@ -7509,6 +7548,109 @@ __metadata:
languageName: node
linkType: hard
"pg-cloudflare@npm:^1.1.1":
version: 1.1.1
resolution: "pg-cloudflare@npm:1.1.1"
checksum: 10c0/a68b957f755be6af813d68ccaf4c906a000fd2ecb362cd281220052cc9e2f6c26da3b88792742387008c30b3bf0d2fa3a0eff04aeb8af4414023c99ae78e07bd
languageName: node
linkType: hard
"pg-connection-string@npm:^2.7.0":
version: 2.7.0
resolution: "pg-connection-string@npm:2.7.0"
checksum: 10c0/50a1496a1c858f9495d78a2c7a66d93ef3602e718aff2953bb5738f3ea616d7f727f32fc20513c9bed127650cd14c1ddc7b458396f4000e689d4b64c65c5c51e
languageName: node
linkType: hard
"pg-int8@npm:1.0.1":
version: 1.0.1
resolution: "pg-int8@npm:1.0.1"
checksum: 10c0/be6a02d851fc2a4ae3e9de81710d861de3ba35ac927268973eb3cb618873a05b9424656df464dd43bd7dc3fc5295c3f5b3c8349494f87c7af50ec59ef14e0b98
languageName: node
linkType: hard
"pg-numeric@npm:1.0.2":
version: 1.0.2
resolution: "pg-numeric@npm:1.0.2"
checksum: 10c0/43dd9884e7b52c79ddc28d2d282d7475fce8bba13452d33c04ceb2e0a65f561edf6699694e8e1c832ff9093770496363183c950dd29608e1bdd98f344b25bca9
languageName: node
linkType: hard
"pg-pool@npm:^3.7.0":
version: 3.7.0
resolution: "pg-pool@npm:3.7.0"
peerDependencies:
pg: ">=8.0"
checksum: 10c0/9128673cf941f288c0cb1a74ca959a9b4f6075ef73b2cc7dece5d4db3dd7043784869e7c12bce2e69ca0df22132a419cc45c2050b4373632856fe8bae9eb94b5
languageName: node
linkType: hard
"pg-protocol@npm:*, pg-protocol@npm:^1.7.0":
version: 1.7.0
resolution: "pg-protocol@npm:1.7.0"
checksum: 10c0/c4af854d9b843c808231c0040fed89f2b9101006157df8da2bb2f62a7dde702de748d852228dc22df41cc7ffddfb526af3bcb34b278b581e9f76a060789186c1
languageName: node
linkType: hard
"pg-types@npm:^2.1.0":
version: 2.2.0
resolution: "pg-types@npm:2.2.0"
dependencies:
pg-int8: "npm:1.0.1"
postgres-array: "npm:~2.0.0"
postgres-bytea: "npm:~1.0.0"
postgres-date: "npm:~1.0.4"
postgres-interval: "npm:^1.1.0"
checksum: 10c0/ab3f8069a323f601cd2d2279ca8c425447dab3f9b61d933b0601d7ffc00d6200df25e26a4290b2b0783b59278198f7dd2ed03e94c4875797919605116a577c65
languageName: node
linkType: hard
"pg-types@npm:^4.0.1":
version: 4.0.2
resolution: "pg-types@npm:4.0.2"
dependencies:
pg-int8: "npm:1.0.1"
pg-numeric: "npm:1.0.2"
postgres-array: "npm:~3.0.1"
postgres-bytea: "npm:~3.0.0"
postgres-date: "npm:~2.1.0"
postgres-interval: "npm:^3.0.0"
postgres-range: "npm:^1.1.1"
checksum: 10c0/780fccda2f3fa2a34e85a72e8e7dadb7d88fbe71ce88f126cb3313f333ad836d02488ec4ff3d94d0c1e5846f735d6e6c6281f8059e6b8919d2180429acaec3e2
languageName: node
linkType: hard
"pg@npm:^8.13.1":
version: 8.13.1
resolution: "pg@npm:8.13.1"
dependencies:
pg-cloudflare: "npm:^1.1.1"
pg-connection-string: "npm:^2.7.0"
pg-pool: "npm:^3.7.0"
pg-protocol: "npm:^1.7.0"
pg-types: "npm:^2.1.0"
pgpass: "npm:1.x"
peerDependencies:
pg-native: ">=3.0.1"
dependenciesMeta:
pg-cloudflare:
optional: true
peerDependenciesMeta:
pg-native:
optional: true
checksum: 10c0/c13bc661cbdb115337bc8519254836faf4bd79106dfd7ed588c8ece8c8b2dd3b7376bfec9a9a2f7646fa095b0b310cec77a83c3ba2ea4872331446eb93fd9055
languageName: node
linkType: hard
"pgpass@npm:1.x":
version: 1.0.5
resolution: "pgpass@npm:1.0.5"
dependencies:
split2: "npm:^4.1.0"
checksum: 10c0/5ea6c9b2de04c33abb08d33a2dded303c4a3c7162a9264519cbe85c0a9857d712463140ba42fad0c7cd4b21f644dd870b45bb2e02fcbe505b4de0744fd802c1d
languageName: node
linkType: hard
"picocolors@npm:^1.0.0, picocolors@npm:^1.1.0, picocolors@npm:^1.1.1":
version: 1.1.1
resolution: "picocolors@npm:1.1.1"
@@ -7550,6 +7692,7 @@ __metadata:
dependencies:
"@auth/prisma-adapter": "npm:^2.7.4"
"@hookform/resolvers": "npm:^3.9.1"
"@prisma/adapter-pg": "npm:^6.1.0"
"@prisma/client": "npm:^6.1.0"
"@radix-ui/react-accordion": "npm:^1.2.1"
"@radix-ui/react-alert-dialog": "npm:^1.1.2"
@@ -7585,6 +7728,7 @@ __metadata:
"@tanstack/react-table": "npm:^8.20.5"
"@types/eslint-plugin-tailwindcss": "npm:^3"
"@types/node": "npm:^20"
"@types/pg": "npm:^8"
"@types/react": "npm:types-react@19.0.0-rc.1"
"@types/react-dom": "npm:types-react-dom@19.0.0-rc.1"
"@types/ws": "npm:^8.5.13"
@@ -7611,6 +7755,7 @@ __metadata:
next-themes: "npm:^0.3.0"
nodemailer: "npm:^6.9.16"
npm-check-updates: "npm:^17.1.13"
pg: "npm:^8.13.1"
postcss: "npm:^8"
prisma: "npm:^6.1.0"
react: "npm:19.0.0"
@@ -7633,7 +7778,6 @@ __metadata:
ws: "npm:^8.18.0"
zenstack: "npm:2.10.2"
zod: "npm:^3.23.8"
zustand: "npm:^5.0.2"
languageName: unknown
linkType: soft
@@ -7736,6 +7880,73 @@ __metadata:
languageName: node
linkType: hard
"postgres-array@npm:3.0.2, postgres-array@npm:~3.0.1":
version: 3.0.2
resolution: "postgres-array@npm:3.0.2"
checksum: 10c0/644aa071f67a66a59f641f8e623887d2b915bc102a32643e2aa8b54c11acd343c5ad97831ea444dd37bd4b921ba35add4aa2cb0c6b76700a8252c2324aeba5b4
languageName: node
linkType: hard
"postgres-array@npm:~2.0.0":
version: 2.0.0
resolution: "postgres-array@npm:2.0.0"
checksum: 10c0/cbd56207e4141d7fbf08c86f2aebf21fa7064943d3f808ec85f442ff94b48d891e7a144cc02665fb2de5dbcb9b8e3183a2ac749959e794b4a4cfd379d7a21d08
languageName: node
linkType: hard
"postgres-bytea@npm:~1.0.0":
version: 1.0.0
resolution: "postgres-bytea@npm:1.0.0"
checksum: 10c0/febf2364b8a8953695cac159eeb94542ead5886792a9627b97e33f6b5bb6e263bc0706ab47ec221516e79fbd6b2452d668841830fb3b49ec6c0fc29be61892ce
languageName: node
linkType: hard
"postgres-bytea@npm:~3.0.0":
version: 3.0.0
resolution: "postgres-bytea@npm:3.0.0"
dependencies:
obuf: "npm:~1.1.2"
checksum: 10c0/41c79cc48aa730c5ba3eda6ab989a940034f07a1f57b8f2777dce56f1b8cca16c5870582932b5b10cc605048aef9b6157e06253c871b4717cafc6d00f55376aa
languageName: node
linkType: hard
"postgres-date@npm:~1.0.4":
version: 1.0.7
resolution: "postgres-date@npm:1.0.7"
checksum: 10c0/0ff91fccc64003e10b767fcfeefb5eaffbc522c93aa65d5051c49b3c4ce6cb93ab091a7d22877a90ad60b8874202c6f1d0f935f38a7235ed3b258efd54b97ca9
languageName: node
linkType: hard
"postgres-date@npm:~2.1.0":
version: 2.1.0
resolution: "postgres-date@npm:2.1.0"
checksum: 10c0/00a7472c10788f6b0d08d24108bf1eb80858de1bd6317740198a564918ea4a69b80c98148167b92ae688abd606483020d0de0dd3a36f3ea9a3e26bbeef3464f4
languageName: node
linkType: hard
"postgres-interval@npm:^1.1.0":
version: 1.2.0
resolution: "postgres-interval@npm:1.2.0"
dependencies:
xtend: "npm:^4.0.0"
checksum: 10c0/c1734c3cb79e7f22579af0b268a463b1fa1d084e742a02a7a290c4f041e349456f3bee3b4ee0bb3f226828597f7b76deb615c1b857db9a742c45520100456272
languageName: node
linkType: hard
"postgres-interval@npm:^3.0.0":
version: 3.0.0
resolution: "postgres-interval@npm:3.0.0"
checksum: 10c0/8b570b30ea37c685e26d136d34460f246f98935a1533defc4b53bb05ee23ae3dc7475b718ec7ea607a57894d8c6b4f1adf67ca9cc83a75bdacffd427d5c68de8
languageName: node
linkType: hard
"postgres-range@npm:^1.1.1":
version: 1.1.4
resolution: "postgres-range@npm:1.1.4"
checksum: 10c0/254494ef81df208e0adeae6b66ce394aba37914ea14c7ece55a45fb6691b7db04bee74c825380a47c887a9f87158fd3d86f758f9cc60b76d3a38ce5aca7912e8
languageName: node
linkType: hard
"preact-render-to-string@npm:5.2.3":
version: 5.2.3
resolution: "preact-render-to-string@npm:5.2.3"
@@ -8751,6 +8962,13 @@ __metadata:
languageName: node
linkType: hard
"split2@npm:^4.1.0":
version: 4.2.0
resolution: "split2@npm:4.2.0"
checksum: 10c0/b292beb8ce9215f8c642bb68be6249c5a4c7f332fc8ecadae7be5cbdf1ea95addc95f0459ef2e7ad9d45fd1064698a097e4eb211c83e772b49bc0ee423e91534
languageName: node
linkType: hard
"sprintf-js@npm:^1.1.3":
version: 1.1.3
resolution: "sprintf-js@npm:1.1.3"
@@ -9943,6 +10161,13 @@ __metadata:
languageName: node
linkType: hard
"xtend@npm:^4.0.0":
version: 4.0.2
resolution: "xtend@npm:4.0.2"
checksum: 10c0/366ae4783eec6100f8a02dff02ac907bf29f9a00b82ac0264b4d8b832ead18306797e283cf19de776538babfdcb2101375ec5646b59f08c52128ac4ab812ed0e
languageName: node
linkType: hard
"yallist@npm:^3.0.2":
version: 3.1.1
resolution: "yallist@npm:3.1.1"
@@ -10038,24 +10263,3 @@ __metadata:
checksum: 10c0/0223d21dbaa15d8928fe0da3b54696391d8e3e1e2d0283a1a070b5980a1dbba945ce631c2d1eccc088fdbad0f2dfa40155590bf83732d3ac4fcca2cc9237591b
languageName: node
linkType: hard
"zustand@npm:^5.0.2":
version: 5.0.2
resolution: "zustand@npm:5.0.2"
peerDependencies:
"@types/react": ">=18.0.0"
immer: ">=9.0.6"
react: ">=18.0.0"
use-sync-external-store: ">=1.2.0"
peerDependenciesMeta:
"@types/react":
optional: true
immer:
optional: true
react:
optional: true
use-sync-external-store:
optional: true
checksum: 10c0/d9bb048d8129fd1aaed3fda974991b15a7c9c31ef06f78e9bf5c4b3678f249850764a6dadb8c93127257d07831995cf7a048281658a37c5d1143ad6f397fe37c
languageName: node
linkType: hard