From d2d48ca39c4bb88357a3511fc3606aa76afd2157 Mon Sep 17 00:00:00 2001 From: Kai Ritthaler Date: Mon, 30 Jun 2025 21:49:51 +0200 Subject: [PATCH] moved project to docker --- code/backend/package.json | 10 +- code/backend/scripts/install.json | 38 +- code/backend/scripts/install.ts | 26 +- .../src/controllers/getPublicPresignedUrl.ts | 18 + .../backend/src/controllers/postController.ts | 13 +- .../src/controllers/profileController.ts | 34 +- .../backend/src/controllers/userController.ts | 2 +- code/backend/src/routes/userRoutes.ts | 2 +- code/backend/src/server.ts | 52 ++- code/backend/yarn.lock | 438 ++++++++++-------- code/db/docker-compose.yaml | 33 -- code/docker/Dockerfile | 40 ++ code/{db => docker}/ERP.png | Bin code/{db => docker}/README.md | 0 code/docker/docker-compose.yaml | 72 +++ code/frontend/src/api/axios.ts | 12 +- code/frontend/src/components/profile/Bio.tsx | 14 +- code/frontend/src/components/profile/bio.css | 65 +-- .../src/pages/404Page/NotFoundPage.tsx | 3 +- code/frontend/src/pages/profile.css | 17 + 20 files changed, 570 insertions(+), 319 deletions(-) create mode 100644 code/backend/src/controllers/getPublicPresignedUrl.ts delete mode 100644 code/db/docker-compose.yaml create mode 100644 code/docker/Dockerfile rename code/{db => docker}/ERP.png (100%) rename code/{db => docker}/README.md (100%) create mode 100644 code/docker/docker-compose.yaml diff --git a/code/backend/package.json b/code/backend/package.json index 049d92c..ebe0331 100644 --- a/code/backend/package.json +++ b/code/backend/package.json @@ -4,10 +4,11 @@ "main": "index.js", "license": "MIT", "dependencies": { - "bcryptjs": "^3.0.2", + "bcrypt": "^6.0.0", "cors": "^2.8.5", "dotenv": "^16.5.0", "express": "^5.1.0", + "http-proxy-middleware": "^3.0.5", "http-status-codes": "^2.3.0", "jsonwebtoken": "^9.0.2", "minio": "^8.0.5", @@ -20,7 +21,7 @@ }, "devDependencies": { "@prisma/client": "^6.9.0", - "@types/bcryptjs": "^3.0.0", + "@types/bcrypt": "^5.0.2", "@types/cors": "^2.8.19", "@types/express": "^5.0.1", "@types/jsonwebtoken": "^9.0.9", @@ -37,12 +38,13 @@ "typescript": "^5.8.3" }, "scripts": { - "start-containers": "docker compose -f ../db/docker-compose.yaml --env-file .env up -d --wait", + "start-containers": "docker compose -f ../docker/docker-compose.yaml --env-file .env up -d --wait", "stop-containers": "docker-compose down", "start": "yarn start-containers && nodemon src/server.ts", "start-no-docker": "nodemon src/server.ts", "install-script": "yarn install && yarn prisma generate && ts-node scripts/install.ts", "build": "tsc", - "dev": "ts-node-dev --respawn src/server.ts" + "serve": "NODE_ENV=production node dist/server.js", + "docker": "cd ../docker/ && docker compose build node-app && docker compose --profile production up" } } diff --git a/code/backend/scripts/install.json b/code/backend/scripts/install.json index ec010cf..b378ca3 100644 --- a/code/backend/scripts/install.json +++ b/code/backend/scripts/install.json @@ -34,7 +34,43 @@ "name": "MINIO_PASSWORD", "generated": false, "hide": true, - "minLength":8 + "minLength": 8 + }, + { + "name": "MINIO_ENDPOINT", + "generated": false, + "default": "localhost", + "hide": false + }, + { + "name": "MINIO_PORT", + "generated": false, + "default": "9000", + "hide": false + }, + { + "name": "MINIO_USE_SSL", + "generated": false, + "default": "false", + "hide": false + }, + { + "name": "PORT", + "generated": false, + "default": "3000", + "hide": false + }, + { + "name": "HOST", + "generated": false, + "default": "0.0.0.0", + "hide": false + }, + { + "name": "CORS_ORIGIN", + "generated": false, + "default": "http://localhost:3000", + "hide": false } ] } diff --git a/code/backend/scripts/install.ts b/code/backend/scripts/install.ts index 271d445..0250954 100644 --- a/code/backend/scripts/install.ts +++ b/code/backend/scripts/install.ts @@ -27,20 +27,23 @@ const config: json_config = JSON.parse(raw); // Parse the JSON file //check if there is a .env and if it has the correct settings let missingConfigs: env_config[] = []; -if (fs.existsSync(".env")) { +if (fs.existsSync("../docker/.env")) { dotenv.config(); for (const setting of config.requiredKeys) { - if (!process.env[setting.name] || process.env[setting.name]!.length <= setting.minLength) { + if ( + !process.env[setting.name] || + process.env[setting.name]!.length <= setting.minLength + ) { missingConfigs.push(setting); } } } else { missingConfigs = config.requiredKeys; } - - if (missingConfigs.length < 1 ) { - // if it`s all set abort the installation - console.log("All required settings are already set in .env."); + +if (missingConfigs.length < 1) { + // if it`s all set abort the installation + console.log("All required settings are already set in .env."); } else { // getting user input for the PostgreSQL username and password console.log("generrating .env file"); @@ -54,9 +57,12 @@ if (fs.existsSync(".env")) { ); } while (!input || input.length < setting.minLength); process.env[setting.name] = input; - } else if (setting.name === "TOKEN_SECRET" || setting.name === "REFRESH_TOKEN_SECRET") { + } else if ( + setting.name === "TOKEN_SECRET" || + setting.name === "REFRESH_TOKEN_SECRET" + ) { // generating a random JWT secret - const jwtSecret: string = crypto.randomBytes(32).toString("hex"); // 64 character + const jwtSecret: string = crypto.randomBytes(32).toString("hex"); // 64 character process.env[setting.name] = jwtSecret; } } @@ -69,7 +75,7 @@ if (fs.existsSync(".env")) { // writing the .env file try { - fs.writeFileSync(".env", env); + fs.writeFileSync("../docker/.env", env); console.log("File has been written successfully."); } catch (err) { console.error("Error writing to file:", err); @@ -106,6 +112,6 @@ let failed: boolean = false; console.log("Bucket 'images' created successfully."); } - console.log(failed?"installation failed":"Installation complete"); + console.log(failed ? "installation failed" : "Installation complete"); process.exit(0); // Exit the process after all commands are executed })(); diff --git a/code/backend/src/controllers/getPublicPresignedUrl.ts b/code/backend/src/controllers/getPublicPresignedUrl.ts new file mode 100644 index 0000000..c6c40a1 --- /dev/null +++ b/code/backend/src/controllers/getPublicPresignedUrl.ts @@ -0,0 +1,18 @@ +import { minioClient, minIOUrl, NODE_ENV } from "../server"; + +export async function getPublicPresignedUrl( + bucketName: string, + objectName: string +): Promise { + const url = await minioClient.presignedGetObject( + bucketName, + objectName, + 3600 + ); + let presignedUrl: string = url; + console.log(NODE_ENV, "Node env"); + if (NODE_ENV === "production") { + presignedUrl = url.replace(minIOUrl, "/media"); + } + return presignedUrl; +} diff --git a/code/backend/src/controllers/postController.ts b/code/backend/src/controllers/postController.ts index 3b88c48..e2ffe9e 100644 --- a/code/backend/src/controllers/postController.ts +++ b/code/backend/src/controllers/postController.ts @@ -5,6 +5,7 @@ import { JwtPayload } from "jsonwebtoken"; import { PrismaClient, Post } from "../../prisma/app/generated/prisma/client"; import { minioClient } from "../server"; import { uploadPostSchema } from "../schemas/postSchemas"; +import { getPublicPresignedUrl } from "./getPublicPresignedUrl"; dotenv.config(); const prisma = new PrismaClient(); @@ -18,11 +19,7 @@ export const uploadPost = async (req: Request, res: Response) => { files.map(async (file) => { const objectName = `${user.sub}/posts/${Date.now()}-${file.originalname}`; await minioClient.putObject(BUCKET, objectName, file.buffer); - const url = await minioClient.presignedGetObject( - BUCKET, - objectName, - 60 * 10 - ); + const url = await getPublicPresignedUrl(BUCKET, objectName); return { originalName: file.originalname, @@ -152,11 +149,7 @@ export const getPost = async (req: Request, res: Response) => { return { originalName: image.originalFilename, mimetype: image.mimeType, - url: await minioClient.presignedGetObject( - image.bucket, - image.objectName, - 60 * 5 - ), + url: await getPublicPresignedUrl(image.bucket, image.objectName), }; } catch (err) { return null; diff --git a/code/backend/src/controllers/profileController.ts b/code/backend/src/controllers/profileController.ts index 4f8d017..49cc215 100644 --- a/code/backend/src/controllers/profileController.ts +++ b/code/backend/src/controllers/profileController.ts @@ -3,8 +3,8 @@ import { JwtPayload } from "jsonwebtoken"; import { PrismaClient } from "../../prisma/app/generated/prisma/client"; import dotenv from "dotenv"; import { StatusCodes } from "http-status-codes"; -import multer from "multer"; import { minioClient } from "../server"; +import { getPublicPresignedUrl } from "./getPublicPresignedUrl"; const app = express(); app.use(express.json()); @@ -31,10 +31,9 @@ const getUser: (userId: string) => Promise = async ( if (user) { let profilePictureUrl: string | null = null; if (user.profilePicture) { - profilePictureUrl = await minioClient.presignedGetObject( + profilePictureUrl = await getPublicPresignedUrl( user.profilePicture.bucket, - user.profilePicture.objectName, - 60 * 10 + user.profilePicture.objectName ); } const followerCount = await prisma.follow.count({ @@ -74,11 +73,7 @@ export const uploadProfilePicture = async (req: Request, res: Response) => { try { const objectName = `${user.sub}/profile.${file.mimetype.split("/")[1]}`; await minioClient.putObject(BUCKET, objectName, file.buffer); - const url = await minioClient.presignedGetObject( - BUCKET, - objectName, - 60 * 10 - ); + const url = await getPublicPresignedUrl(BUCKET, objectName); const oldImage = await prisma.user.findUnique({ where: { id: user.sub }, select: { profilePictureId: true }, @@ -159,10 +154,9 @@ export const getProfilePicture = async (req: Request, res: Response) => { return; } - const profilePictureUrl = await minioClient.presignedGetObject( + const profilePictureUrl = await getPublicPresignedUrl( user.profilePicture.bucket, - user.profilePicture.objectName, - 60 * 10 // 10 minutes expiration + user.profilePicture.objectName ); res.status(StatusCodes.OK).json({ url: profilePictureUrl }); @@ -228,22 +222,22 @@ export const getProfile = async (req: Request, res: Response) => { const publicUser: PublicUser | undefined = await getUser(user.id); - let isFollowing : boolean = false; - if(requestingUser) { + let isFollowing: boolean = false; + if (requestingUser) { const followingData = await prisma.follow.findFirst({ where: { followedUserId: user.id, followingUserId: requestingUser.id, - } - }) - if(followingData) { - isFollowing = true; - } + }, + }); + if (followingData) { + isFollowing = true; + } } res.status(StatusCodes.OK).json({ message: "User found", - data: {...publicUser, isFollowing}, + data: { ...publicUser, isFollowing }, }); } catch (err) { console.error(err); diff --git a/code/backend/src/controllers/userController.ts b/code/backend/src/controllers/userController.ts index 52d4dc8..5e71c2d 100644 --- a/code/backend/src/controllers/userController.ts +++ b/code/backend/src/controllers/userController.ts @@ -7,7 +7,7 @@ import { import { UserLoginDto, UserRegistrationDto } from "../schemas/userSchemas"; import jwt, { TokenExpiredError } from "jsonwebtoken"; import dotenv from "dotenv"; -import bcrypt from "bcryptjs"; +import bcrypt from "bcrypt"; import { StatusCodes } from "http-status-codes"; import { RefreshTokenPayload } from "../types/tokens"; const app = express(); diff --git a/code/backend/src/routes/userRoutes.ts b/code/backend/src/routes/userRoutes.ts index 29b6489..feda507 100644 --- a/code/backend/src/routes/userRoutes.ts +++ b/code/backend/src/routes/userRoutes.ts @@ -124,7 +124,7 @@ userRouter.get("/refreshToken", refreshToken); /** * @swagger - * /api/user/logout/: + * /api/user/logout: * delete: * summary: logout * tags: [Auth] diff --git a/code/backend/src/server.ts b/code/backend/src/server.ts index 6c33d86..0ca92ab 100644 --- a/code/backend/src/server.ts +++ b/code/backend/src/server.ts @@ -7,31 +7,41 @@ import profileRouter from "./routes/profileRoutes"; import followerRouter from "./routes/followerRoutes"; import bodyParser from "body-parser"; import cors from "cors"; -dotenv.config(); +import fs from "fs"; +import { createProxyMiddleware, Options } from "http-proxy-middleware"; +dotenv.config(); +export const NODE_ENV = process.env.NODE_ENV || "dev"; const app = express(); -const port = 3001; +const port = process.env.PORT; app.use( cors({ - origin: "http://localhost:3000", + origin: process.env.CORS_ORIGIN, credentials: true, exposedHeaders: ["Authorization", "Refresh-Token"], }) ); // minIO config +const minioEndpoint = process.env.MINIO_ENDPOINT || "localhost"; +const minioPort = parseInt(process.env.MINIO_PORT || "9000"); +export const minIOUrl = `http://${minioEndpoint}:${minioPort}`; + +console.log(`Connecting to MinIO at ${minioEndpoint}:${minioPort}`); + export const minioClient = new Client({ - endPoint: "localhost", // Replace with your MinIO server URL - port: 9000, // Default MinIO port - useSSL: false, // Set to true if using HTTPS - accessKey: process.env.MINIO_USER, // minIO username/access key - secretKey: process.env.MINIO_PASSWORD, // MinIO password/secret key + endPoint: minioEndpoint, + port: minioPort, + useSSL: false, + accessKey: process.env.MINIO_USER || "", + secretKey: process.env.MINIO_PASSWORD || "", }); //swagger configuration import swaggerJSDoc from "swagger-jsdoc"; import swaggerUi from "swagger-ui-express"; import { deleteExpiredTokens } from "./tasks/deleteTokens"; import feedRouter from "./routes/feedRoutes"; +import path from "path"; const options = { definition: { @@ -81,6 +91,32 @@ app.use("/api/posts", postRouter); app.use("/api/profile", profileRouter); app.use("/api/feed", feedRouter); app.use("/api/follower/", followerRouter); +const minioProxyOptions: Options = { + target: minIOUrl, + changeOrigin: true, + pathRewrite: { + "^/media": "/", + }, +}; +app.use("/media/", createProxyMiddleware(minioProxyOptions)); +// In production builds, NODE_ENV will be "production" +console.log(NODE_ENV); +if (process.env.NODE_ENV === "production") { + // serve frontend + const publicDir = path.join(__dirname, "../public/"); + console.log(publicDir); + app.use(express.static(publicDir)); + + app.get(/.*/, (req, res) => { + const indexPath = path.join(publicDir, "index.html"); + if (fs.existsSync(indexPath)) { + res.sendFile(indexPath); // Using absolute path created with path.join + } else { + res.status(404).send("Frontend build not found"); + } + }); +} + app.listen(port, () => { console.log(`Server läuft auf http://localhost:${port}`); }); diff --git a/code/backend/yarn.lock b/code/backend/yarn.lock index 7f117bc..f36a522 100644 --- a/code/backend/yarn.lock +++ b/code/backend/yarn.lock @@ -47,9 +47,9 @@ integrity sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw== "@jridgewell/sourcemap-codec@^1.4.10": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" - integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + version "1.5.2" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.2.tgz#4f25c8f17f28ccf70ed16e03f8fbf6d3998cb8fd" + integrity sha512-gKYheCylLIedI+CSZoDtGkFV9YEBxRRVcfCH7OfAqh4TyUyRjEE6WVE/aXDXX0p8BIe/QgLcaAoI0220KRRFgg== "@jridgewell/trace-mapping@0.3.9": version "0.3.9" @@ -65,52 +65,52 @@ integrity sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg== "@prisma/client@^6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@prisma/client/-/client-6.9.0.tgz#3779ba71a4c9fe8c329506f126dc70b71410c358" - integrity sha512-Gg7j1hwy3SgF1KHrh0PZsYvAaykeR0PaxusnLXydehS96voYCGt1U5zVR31NIouYc63hWzidcrir1a7AIyCsNQ== + version "6.10.1" + resolved "https://registry.yarnpkg.com/@prisma/client/-/client-6.10.1.tgz#f5cf8731727ea833b53524f300458d0adbb5c58f" + integrity sha512-Re4pMlcUsQsUTAYMK7EJ4Bw2kg3WfZAAlr8GjORJaK4VOP6LxRQUQ1TuLnxcF42XqGkWQ36q5CQF1yVadANQ6w== -"@prisma/config@6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@prisma/config/-/config-6.9.0.tgz#c3072b38cd65a88ea82b41d07e1a5e5fef592d8d" - integrity sha512-Wcfk8/lN3WRJd5w4jmNQkUwhUw0eksaU/+BlAJwPQKW10k0h0LC9PD/6TQFmqKVbHQL0vG2z266r0S1MPzzhbA== +"@prisma/config@6.10.1": + version "6.10.1" + resolved "https://registry.yarnpkg.com/@prisma/config/-/config-6.10.1.tgz#d67364aa330af3c5069009f987863806ce2acaad" + integrity sha512-kz4/bnqrOrzWo8KzYguN0cden4CzLJJ+2VSpKtF8utHS3l1JS0Lhv6BLwpOX6X9yNreTbZQZwewb+/BMPDCIYQ== dependencies: jiti "2.4.2" -"@prisma/debug@6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-6.9.0.tgz#0c69adb1272259da29374f758372eac7621ef9ac" - integrity sha512-bFeur/qi/Q+Mqk4JdQ3R38upSYPebv5aOyD1RKywVD+rAMLtRkmTFn28ZuTtVOnZHEdtxnNOCH+bPIeSGz1+Fg== +"@prisma/debug@6.10.1": + version "6.10.1" + resolved "https://registry.yarnpkg.com/@prisma/debug/-/debug-6.10.1.tgz#8d4b2219c27b09ba747148785e9f0b7efd1ae343" + integrity sha512-k2YT53cWxv9OLjW4zSYTZ6Z7j0gPfCzcr2Mj99qsuvlxr8WAKSZ2NcSR0zLf/mP4oxnYG842IMj3utTgcd7CaA== -"@prisma/engines-version@6.9.0-10.81e4af48011447c3cc503a190e86995b66d2a28e": - version "6.9.0-10.81e4af48011447c3cc503a190e86995b66d2a28e" - resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-6.9.0-10.81e4af48011447c3cc503a190e86995b66d2a28e.tgz#360c7132f2083cafcb39f37ab4debea6189707d4" - integrity sha512-Qp9gMoBHgqhKlrvumZWujmuD7q4DV/gooEyPCLtbkc13EZdSz2RsGUJ5mHb3RJgAbk+dm6XenqG7obJEhXcJ6Q== +"@prisma/engines-version@6.10.1-1.9b628578b3b7cae625e8c927178f15a170e74a9c": + version "6.10.1-1.9b628578b3b7cae625e8c927178f15a170e74a9c" + resolved "https://registry.yarnpkg.com/@prisma/engines-version/-/engines-version-6.10.1-1.9b628578b3b7cae625e8c927178f15a170e74a9c.tgz#0251f10e7b04e0a5d05d15b9823da8bc4fff2a5c" + integrity sha512-ZJFTsEqapiTYVzXya6TUKYDFnSWCNegfUiG5ik9fleQva5Sk3DNyyUi7X1+0ZxWFHwHDr6BZV5Vm+iwP+LlciA== -"@prisma/engines@6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-6.9.0.tgz#35c69f95ff47de852d261c5ef626c46c922a9200" - integrity sha512-im0X0bwDLA0244CDf8fuvnLuCQcBBdAGgr+ByvGfQY9wWl6EA+kRGwVk8ZIpG65rnlOwtaWIr/ZcEU5pNVvq9g== +"@prisma/engines@6.10.1": + version "6.10.1" + resolved "https://registry.yarnpkg.com/@prisma/engines/-/engines-6.10.1.tgz#bd3b2d604498b756ecd7c76698cae9221f962805" + integrity sha512-Q07P5rS2iPwk2IQr/rUQJ42tHjpPyFcbiH7PXZlV81Ryr9NYIgdxcUrwgVOWVm5T7ap02C0dNd1dpnNcSWig8A== dependencies: - "@prisma/debug" "6.9.0" - "@prisma/engines-version" "6.9.0-10.81e4af48011447c3cc503a190e86995b66d2a28e" - "@prisma/fetch-engine" "6.9.0" - "@prisma/get-platform" "6.9.0" + "@prisma/debug" "6.10.1" + "@prisma/engines-version" "6.10.1-1.9b628578b3b7cae625e8c927178f15a170e74a9c" + "@prisma/fetch-engine" "6.10.1" + "@prisma/get-platform" "6.10.1" -"@prisma/fetch-engine@6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-6.9.0.tgz#0559705b2787da9864ba910ddc51a428591236d7" - integrity sha512-PMKhJdl4fOdeE3J3NkcWZ+tf3W6rx3ht/rLU8w4SXFRcLhd5+3VcqY4Kslpdm8osca4ej3gTfB3+cSk5pGxgFg== +"@prisma/fetch-engine@6.10.1": + version "6.10.1" + resolved "https://registry.yarnpkg.com/@prisma/fetch-engine/-/fetch-engine-6.10.1.tgz#321aa7a94305c754d2da0cbb451b179b24edd37a" + integrity sha512-clmbG/Jgmrc/n6Y77QcBmAUlq9LrwI9Dbgy4pq5jeEARBpRCWJDJ7PWW1P8p0LfFU0i5fsyO7FqRzRB8mkdS4g== dependencies: - "@prisma/debug" "6.9.0" - "@prisma/engines-version" "6.9.0-10.81e4af48011447c3cc503a190e86995b66d2a28e" - "@prisma/get-platform" "6.9.0" + "@prisma/debug" "6.10.1" + "@prisma/engines-version" "6.10.1-1.9b628578b3b7cae625e8c927178f15a170e74a9c" + "@prisma/get-platform" "6.10.1" -"@prisma/get-platform@6.9.0": - version "6.9.0" - resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-6.9.0.tgz#f0b02707930ebebd9d2ccf536280301a35a0f859" - integrity sha512-/B4n+5V1LI/1JQcHp+sUpyRT1bBgZVPHbsC4lt4/19Xp4jvNIVcq5KYNtQDk5e/ukTSjo9PZVAxxy9ieFtlpTQ== +"@prisma/get-platform@6.10.1": + version "6.10.1" + resolved "https://registry.yarnpkg.com/@prisma/get-platform/-/get-platform-6.10.1.tgz#28460715162754a7867c389b55485cbb18b75268" + integrity sha512-4CY5ndKylcsce9Mv+VWp5obbR2/86SHOLVV053pwIkhVtT9C9A83yqiqI/5kJM9T1v1u1qco/bYjDKycmei9HA== dependencies: - "@prisma/debug" "6.9.0" + "@prisma/debug" "6.10.1" "@scarf/scarf@=1.4.0": version "1.4.0" @@ -137,17 +137,17 @@ resolved "https://registry.yarnpkg.com/@tsconfig/node16/-/node16-1.0.4.tgz#0b92dcc0cc1c81f6f306a381f28e31b1a56536e9" integrity sha512-vxhUy4J8lyeyinH7Azl1pdd43GJhZH/tP2weN8TntQblOY+A0XbT8DJk1/oCPuOOyg/Ja757rG0CgHcWC8OfMA== -"@types/bcryptjs@^3.0.0": - version "3.0.0" - resolved "https://registry.yarnpkg.com/@types/bcryptjs/-/bcryptjs-3.0.0.tgz#d7be11653aa82cf17ffee4f3925f1f80cfc1add2" - integrity sha512-WRZOuCuaz8UcZZE4R5HXTco2goQSI2XxjGY3hbM/xDvwmqFWd4ivooImsMx65OKM6CtNKbnZ5YL+YwAwK7c1dg== +"@types/bcrypt@^5.0.2": + version "5.0.2" + resolved "https://registry.yarnpkg.com/@types/bcrypt/-/bcrypt-5.0.2.tgz#22fddc11945ea4fbc3655b3e8b8847cc9f811477" + integrity sha512-6atioO8Y75fNcbmj0G7UjI9lXN2pQ/IGJ2FWT4a/btd0Lk9lQalHLKhkgKVZ3r+spnmWUKfbMi1GEe9wyHQfNQ== dependencies: - bcryptjs "*" + "@types/node" "*" "@types/body-parser@*": - version "1.19.5" - resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.5.tgz#04ce9a3b677dc8bd681a17da1ab9835dc9d3ede4" - integrity sha512-fB3Zu92ucau0iQ0JMCFQE7b/dv8Ot07NI3KaZIkIUNXq82k4eBAqUaneXfleGY9JWskeS9y+u0nXMyspcuQrCg== + version "1.19.6" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.6.tgz#1859bebb8fd7dac9918a45d54c1971ab8b5af474" + integrity sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g== dependencies: "@types/connect" "*" "@types/node" "*" @@ -177,18 +177,25 @@ "@types/send" "*" "@types/express@*", "@types/express@^5.0.1": - version "5.0.1" - resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.1.tgz#138d741c6e5db8cc273bec5285cd6e9d0779fc9f" - integrity sha512-UZUw8vjpWFXuDnjFTh7/5c2TWDlQqeXHi6hcN7F2XSVT5P+WmUnnbFS3KA6Jnc6IsEqI2qCVu2bK0R0J4A8ZQQ== + version "5.0.3" + resolved "https://registry.yarnpkg.com/@types/express/-/express-5.0.3.tgz#6c4bc6acddc2e2a587142e1d8be0bce20757e956" + integrity sha512-wGA0NX93b19/dZC1J18tKWVIYWyyF2ZjT9vin/NRu0qzzvfVzWjs04iq2rQ3H65vCTQYlRqs3YHfY7zjdV+9Kw== dependencies: "@types/body-parser" "*" "@types/express-serve-static-core" "^5.0.0" "@types/serve-static" "*" "@types/http-errors@*": - version "2.0.4" - resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.4.tgz#7eb47726c391b7345a6ec35ad7f4de469cf5ba4f" - integrity sha512-D0CFMMtydbJAegzOyHjtiKPLlvnm3iTZyZRSZoLq2mRhDdmLfIWOCYPfQJ4cu2erKghU++QvjcUjp/5h7hESpA== + version "2.0.5" + resolved "https://registry.yarnpkg.com/@types/http-errors/-/http-errors-2.0.5.tgz#5b749ab2b16ba113423feb1a64a95dcd30398472" + integrity sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg== + +"@types/http-proxy@^1.17.15": + version "1.17.16" + resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.17.16.tgz#dee360707b35b3cc85afcde89ffeebff7d7f9240" + integrity sha512-sdWoUajOB1cd0A8cRRQ1cfyWNbmFKLAqBB89Y8x5iYyG/mkJHc0YUH8pdWBy2omi9qtCpiIgGjuwO0dQST2l5w== + dependencies: + "@types/node" "*" "@types/json-schema@^7.0.6": version "7.0.15" @@ -196,9 +203,9 @@ integrity sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA== "@types/jsonwebtoken@^9.0.9": - version "9.0.9" - resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.9.tgz#a4c3a446c0ebaaf467a58398382616f416345fb3" - integrity sha512-uoe+GxEuHbvy12OUQct2X9JenKM3qAscquYymuQN4fMWG9DBQtykrQEFcAbVACF7qaLw9BePSodUL0kquqBJpQ== + version "9.0.10" + resolved "https://registry.yarnpkg.com/@types/jsonwebtoken/-/jsonwebtoken-9.0.10.tgz#a7932a47177dcd4283b6146f3bd5c26d82647f09" + integrity sha512-asx5hIG9Qmf/1oStypjanR7iKTv0gXQ1Ov/jfrX6kS/EO0OFni8orbmGCn0672NHR3kXHwpAwR+B368ZGN/2rA== dependencies: "@types/ms" "*" "@types/node" "*" @@ -214,23 +221,30 @@ integrity sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA== "@types/multer@^1.4.12": - version "1.4.12" - resolved "https://registry.yarnpkg.com/@types/multer/-/multer-1.4.12.tgz#da67bd0c809f3a63fe097c458c0d4af1fea50ab7" - integrity sha512-pQ2hoqvXiJt2FP9WQVLPRO+AmiIm/ZYkavPlIQnx282u4ZrVdztx0pkh3jjpQt0Kz+YI0YhSG264y08UJKoUQg== + version "1.4.13" + resolved "https://registry.yarnpkg.com/@types/multer/-/multer-1.4.13.tgz#be483f909a77f13e0624cac3d001859eb12ae68b" + integrity sha512-bhhdtPw7JqCiEfC9Jimx5LqX9BDIPJEh2q/fQ4bqbBPtyEZYr3cvF22NwG0DmPZNYA0CAf2CnqDB4KIGGpJcaw== dependencies: "@types/express" "*" -"@types/node@*", "@types/node@^22.15.2": - version "22.15.12" - resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.12.tgz#9ce54e51e09536faa94e4ec300c4728ee83bfa85" - integrity sha512-K0fpC/ZVeb8G9rm7bH7vI0KAec4XHEhBam616nVJCV51bKzJ6oA3luG4WdKoaztxe70QaNjS/xBmcDLmr4PiGw== +"@types/node@*": + version "24.0.7" + resolved "https://registry.yarnpkg.com/@types/node/-/node-24.0.7.tgz#ee580f7850c7eabaeef61ef96b8d8c04fdf94f53" + integrity sha512-YIEUUr4yf8q8oQoXPpSlnvKNVKDQlPMWrmOcgzoduo7kvA2UF0/BwJ/eMKFTiTtkNL17I0M6Xe2tvwFU7be6iw== + dependencies: + undici-types "~7.8.0" + +"@types/node@^22.15.2": + version "22.15.34" + resolved "https://registry.yarnpkg.com/@types/node/-/node-22.15.34.tgz#3995a6461d2cfc51c81907da0065fc328f6a459e" + integrity sha512-8Y6E5WUupYy1Dd0II32BsWAx5MWdcnRd8L84Oys3veg1YrYtNtzgO4CFhiBg6MDSjk7Ay36HYOnU7/tuOzIzcw== dependencies: undici-types "~6.21.0" "@types/qs@*": - version "6.9.18" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.18.tgz#877292caa91f7c1b213032b34626505b746624c2" - integrity sha512-kK7dgTYDyGqS+e2Q4aK9X3D7q234CIZ1Bv0q/7Z5IwRDoADNU81xXJK/YVyLbLTZCoIwUoDoffFeF+p/eIklAA== + version "6.14.0" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.14.0.tgz#d8b60cecf62f2db0fb68e5e006077b9178b85de5" + integrity sha512-eOunJqu0K1923aExK6y8p6fsihYEn/BYuQ4g0CxAAgFc4b/ZLN4CrsRZ55srTdqoiLzU2B2evC+apEIxprEzkQ== "@types/range-parser@*": version "1.2.7" @@ -243,17 +257,17 @@ integrity sha512-BL7xOf0yKLA6baAX6MMOnYkoflUyj/c7y3pqMRfU0va7XlwHAOTOIo4x55P/qLfMsuaYdJJKubToLqRVmRtRZA== "@types/send@*": - version "0.17.4" - resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.4.tgz#6619cd24e7270793702e4e6a4b958a9010cfc57a" - integrity sha512-x2EM6TJOybec7c52BX0ZspPodMsQUd5L6PRwOunVyVUhXiBSKf3AezDL8Dgvgt5o0UfKNfuA0eMLr2wLT4AiBA== + version "0.17.5" + resolved "https://registry.yarnpkg.com/@types/send/-/send-0.17.5.tgz#d991d4f2b16f2b1ef497131f00a9114290791e74" + integrity sha512-z6F2D3cOStZvuk2SaP6YrwkNO65iTZcwA2ZkSABegdkAh/lf+Aa/YQndZVfmEXT5vgAp6zv06VQ3ejSVjAny4w== dependencies: "@types/mime" "^1" "@types/node" "*" "@types/serve-static@*": - version "1.15.7" - resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.7.tgz#22174bbd74fb97fe303109738e9b5c2f3064f714" - integrity sha512-W8Ym+h8nhuRwaKPaDw34QUkwsGi6Rc4yYqvKFo5rm2FUEhCFbzVWrxXUxuKK8TASjWsysJY0nsmNCGhCOIsrOw== + version "1.15.8" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.15.8.tgz#8180c3fbe4a70e8f00b9f70b9ba7f08f35987877" + integrity sha512-roei0UY3LhpOJvjbIP6ZZFngyLKl5dskOtDhxY5THRSpO+ZI+nzJ+m5yUMzGrp89YRa7lvknKkMYjqQFGwA7Sg== dependencies: "@types/http-errors" "*" "@types/node" "*" @@ -303,9 +317,9 @@ acorn-walk@^8.1.1: acorn "^8.11.0" acorn@^8.11.0, acorn@^8.4.1: - version "8.14.1" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.14.1.tgz#721d5dc10f7d5b5609a891773d47731796935dfb" - integrity sha512-OvQ/2pUDKmgfCg++xsTX1wGxfTaszcHVcTctW4UJB4hibJx2HXxxO5UmVgyjMa+ZDsiaf5wWLXYpRWMmBI0QHg== + version "8.15.0" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.15.0.tgz#a360898bc415edaac46c8241f6383975b930b816" + integrity sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg== anymatch@~3.1.2: version "3.1.3" @@ -347,10 +361,13 @@ balanced-match@^1.0.0: resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee" integrity sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw== -bcryptjs@*, bcryptjs@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/bcryptjs/-/bcryptjs-3.0.2.tgz#caadcca1afefe372ed6e20f86db8e8546361c1ca" - integrity sha512-k38b3XOZKv60C4E2hVsXTolJWfkGRMbILBIe2IBITXciy5bOsTKot5kDrf3ZfufQtQOUN5mXceUEpU1rTl9Uog== +bcrypt@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/bcrypt/-/bcrypt-6.0.0.tgz#86643fddde9bcd0ad91400b063003fa4b0312835" + integrity sha512-cU8v/EGSrnH+HnxV2z0J7/blxH8gq7Xh2JFT6Aroax7UohdmiJJlxApMxtKfuI7z68NvvVcmR78k2LbT6efhRg== + dependencies: + node-addon-api "^8.3.0" + node-gyp-build "^4.8.4" binary-extensions@^2.0.0: version "2.3.0" @@ -380,14 +397,14 @@ body-parser@^2.2.0: type-is "^2.0.0" brace-expansion@^1.1.7: - version "1.1.11" - resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" - integrity sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA== + version "1.1.12" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.12.tgz#ab9b454466e5a8cc3a187beaad580412a9c5b843" + integrity sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg== dependencies: balanced-match "^1.0.0" concat-map "0.0.1" -braces@~3.0.2: +braces@^3.0.3, braces@~3.0.2: version "3.0.3" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.3.tgz#490332f40919452272d55a8480adc0c441358789" integrity sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA== @@ -414,7 +431,7 @@ buffer-from@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5" integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ== -busboy@^1.0.0: +busboy@^1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/busboy/-/busboy-1.6.0.tgz#966ea36a9502e43cdb9146962523b92f531f6893" integrity sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA== @@ -487,14 +504,14 @@ concat-map@0.0.1: resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" integrity sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg== -concat-stream@^1.5.2: - version "1.6.2" - resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" - integrity sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw== +concat-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-2.0.0.tgz#414cf5af790a48c60ab9be4527d56d5e41133cb1" + integrity sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A== dependencies: buffer-from "^1.0.0" inherits "^2.0.3" - readable-stream "^2.2.2" + readable-stream "^3.0.2" typedarray "^0.0.6" content-disposition@^1.0.0: @@ -519,11 +536,6 @@ cookie@^0.7.1: resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.7.2.tgz#556369c472a2ba910f2979891b526b3436237ed7" integrity sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w== -core-util-is@~1.0.0: - version "1.0.3" - resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85" - integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ== - cors@^2.8.5: version "2.8.5" resolved "https://registry.yarnpkg.com/cors/-/cors-2.8.5.tgz#eac11da51592dd86b9f06f6e7ac293b3df875d29" @@ -537,10 +549,10 @@ create-require@^1.1.0: resolved "https://registry.yarnpkg.com/create-require/-/create-require-1.1.1.tgz#c1d7e8f1e5f6cfc9ff65f9cd352d37348756c333" integrity sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ== -debug@^4, debug@^4.3.5, debug@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.0.tgz#2b3f2aea2ffeb776477460267377dc8710faba8a" - integrity sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA== +debug@^4, debug@^4.3.5, debug@^4.3.6, debug@^4.4.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.4.1.tgz#e5a8bc6cbc4c6cd3e64308b0693a3d4fa550189b" + integrity sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ== dependencies: ms "^2.1.3" @@ -576,9 +588,9 @@ doctrine@3.0.0: esutils "^2.0.2" dotenv@^16.5.0: - version "16.5.0" - resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.5.0.tgz#092b49f25f808f020050051d1ff258e404c78692" - integrity sha512-m/C+AwOAr9/W1UOIZUo232ejMNnJAJtYQjUbHoNTBNTJSvqzzDh7vnrei3o3r3m9blf6ZoDkvcw0VmozNRFJxg== + version "16.6.1" + resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-16.6.1.tgz#773f0e69527a8315c7285d5ee73c4459d20a8020" + integrity sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow== dunder-proto@^1.0.1: version "1.0.1" @@ -645,6 +657,11 @@ etag@^1.8.1: resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== +eventemitter3@^4.0.0: + version "4.0.7" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f" + integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== + eventemitter3@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-5.0.1.tgz#53f5ffd0a492ac800721bb42c66b841de96423c4" @@ -714,6 +731,11 @@ finalhandler@^2.1.0: parseurl "^1.3.3" statuses "^2.0.1" +follow-redirects@^1.0.0: + version "1.15.9" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.9.tgz#a604fa10e443bf98ca94228d9eebcc2e8a2c8ee1" + integrity sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ== + for-each@^0.3.5: version "0.3.5" resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.5.tgz#d650688027826920feeb0af747ee7b9421a41d47" @@ -848,6 +870,27 @@ http-errors@2.0.0, http-errors@^2.0.0: statuses "2.0.1" toidentifier "1.0.1" +http-proxy-middleware@^3.0.5: + version "3.0.5" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-3.0.5.tgz#9dcde663edc44079bc5a9c63e03fe5e5d6037fab" + integrity sha512-GLZZm1X38BPY4lkXA01jhwxvDoOkkXqjgVyUzVxiEK4iuRu03PZoYHhHRwxnfhQMDuaxi3vVri0YgSro/1oWqg== + dependencies: + "@types/http-proxy" "^1.17.15" + debug "^4.3.6" + http-proxy "^1.18.1" + is-glob "^4.0.3" + is-plain-object "^5.0.0" + micromatch "^4.0.8" + +http-proxy@^1.18.1: + version "1.18.1" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549" + integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ== + dependencies: + eventemitter3 "^4.0.0" + follow-redirects "^1.0.0" + requires-port "^1.0.0" + http-status-codes@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/http-status-codes/-/http-status-codes-2.3.0.tgz#987fefb28c69f92a43aecc77feec2866349a8bfc" @@ -873,7 +916,7 @@ inflight@^1.0.4: once "^1.3.0" wrappy "1" -inherits@2, inherits@2.0.4, inherits@^2.0.3, inherits@~2.0.3: +inherits@2, inherits@2.0.4, inherits@^2.0.3: version "2.0.4" resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== @@ -930,7 +973,7 @@ is-generator-function@^1.0.7: has-tostringtag "^1.0.2" safe-regex-test "^1.1.0" -is-glob@^4.0.1, is-glob@~4.0.1: +is-glob@^4.0.1, is-glob@^4.0.3, is-glob@~4.0.1: version "4.0.3" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.3.tgz#64f61e42cbbb2eec2071a9dac0b28ba1e65d5084" integrity sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg== @@ -942,6 +985,11 @@ is-number@^7.0.0: resolved "https://registry.yarnpkg.com/is-number/-/is-number-7.0.0.tgz#7535345b896734d5f80c4d06c50955527a14f12b" integrity sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng== +is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + is-promise@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-4.0.0.tgz#42ff9f84206c1991d26debf520dd5c01042dd2f3" @@ -964,11 +1012,6 @@ is-typed-array@^1.1.3: dependencies: which-typed-array "^1.1.16" -isarray@~1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" - integrity sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ== - jiti@2.4.2: version "2.4.2" resolved "https://registry.yarnpkg.com/jiti/-/jiti-2.4.2.tgz#d19b7732ebb6116b06e2038da74a55366faef560" @@ -1094,6 +1137,14 @@ merge-descriptors@^2.0.0: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-2.0.0.tgz#ea922f660635a2249ee565e0449f951e6b603808" integrity sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g== +micromatch@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-4.0.8.tgz#d66fa18f3a47076789320b9b1af32bd86d9fa202" + integrity sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA== + dependencies: + braces "^3.0.3" + picomatch "^2.3.1" + mime-db@1.52.0: version "1.52.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.52.0.tgz#bbabcdc02859f4987301c856e3387ce5ec43bf70" @@ -1150,7 +1201,7 @@ minio@^8.0.5: web-encoding "^1.1.5" xml2js "^0.5.0 || ^0.6.2" -mkdirp@^0.5.4: +mkdirp@^0.5.6: version "0.5.6" resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.6.tgz#7def03d2432dcae4ba1d611445c48396062255f6" integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== @@ -1168,23 +1219,33 @@ ms@^2.1.1, ms@^2.1.3: integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== multer@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/multer/-/multer-2.0.0.tgz#47076aa0f7c2c2fd273715e767c6962bf7f94326" - integrity sha512-bS8rPZurbAuHGAnApbM9d4h1wSoYqrOqkE+6a64KLMK9yWU7gJXBDDVklKQ3TPi9DRb85cRs6yXaC0+cjxRtRg== + version "2.0.1" + resolved "https://registry.yarnpkg.com/multer/-/multer-2.0.1.tgz#3ed335ed2b96240e3df9e23780c91cfcf5d29202" + integrity sha512-Ug8bXeTIUlxurg8xLTEskKShvcKDZALo1THEX5E41pYCD2sCVub5/kIRIGqWNoqV6szyLyQKV6mD4QUrWE5GCQ== dependencies: append-field "^1.0.0" - busboy "^1.0.0" - concat-stream "^1.5.2" - mkdirp "^0.5.4" + busboy "^1.6.0" + concat-stream "^2.0.0" + mkdirp "^0.5.6" object-assign "^4.1.1" - type-is "^1.6.4" - xtend "^4.0.0" + type-is "^1.6.18" + xtend "^4.0.2" negotiator@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-1.0.0.tgz#b6c91bb47172d69f93cfd7c357bbb529019b5f6a" integrity sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg== +node-addon-api@^8.3.0: + version "8.4.0" + resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-8.4.0.tgz#8cbc68ee1c216368921a8f63038a23a39cd8ba44" + integrity sha512-D9DI/gXHvVmjHS08SVch0Em8G5S1P+QWtU31appcKT/8wFSPRcdHadIFSAntdMMVM5zz+/DL+bL/gz3UDppqtg== + +node-gyp-build@^4.8.4: + version "4.8.4" + resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.8.4.tgz#8a70ee85464ae52327772a90d66c6077a900cfc8" + integrity sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ== + nodemon@^3.1.10: version "3.1.10" resolved "https://registry.yarnpkg.com/nodemon/-/nodemon-3.1.10.tgz#5015c5eb4fffcb24d98cf9454df14f4fecec9bc1" @@ -1250,32 +1311,32 @@ path-to-regexp@^8.0.0: resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-8.2.0.tgz#73990cc29e57a3ff2a0d914095156df5db79e8b4" integrity sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ== -pg-cloudflare@^1.2.5: - version "1.2.5" - resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.2.5.tgz#2e3649c38a7a9c74a7e5327c8098a2fd9af595bd" - integrity sha512-OOX22Vt0vOSRrdoUPKJ8Wi2OpE/o/h9T8X1s4qSkCedbNah9ei2W2765be8iMVxQUsvgT7zIAT2eIa9fs5+vtg== +pg-cloudflare@^1.2.7: + version "1.2.7" + resolved "https://registry.yarnpkg.com/pg-cloudflare/-/pg-cloudflare-1.2.7.tgz#a1f3d226bab2c45ae75ea54d65ec05ac6cfafbef" + integrity sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg== -pg-connection-string@^2.8.5: - version "2.8.5" - resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.8.5.tgz#82cefd0269cb64a09603342d9b69e8392e6eb6cd" - integrity sha512-Ni8FuZ8yAF+sWZzojvtLE2b03cqjO5jNULcHFfM9ZZ0/JXrgom5pBREbtnAw7oxsxJqHw9Nz/XWORUEL3/IFow== +pg-connection-string@^2.9.1: + version "2.9.1" + resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.9.1.tgz#bb1fd0011e2eb76ac17360dc8fa183b2d3465238" + integrity sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w== pg-int8@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/pg-int8/-/pg-int8-1.0.1.tgz#943bd463bf5b71b4170115f80f8efc9a0c0eb78c" integrity sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw== -pg-pool@^3.9.6: - version "3.9.6" - resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.9.6.tgz#c6fde89dee615d6c262724e68a3a37e9593157fc" - integrity sha512-rFen0G7adh1YmgvrmE5IPIqbb+IgEzENUm+tzm6MLLDSlPRoZVhzU1WdML9PV2W5GOdRA9qBKURlbt1OsXOsPw== +pg-pool@^3.10.1: + version "3.10.1" + resolved "https://registry.yarnpkg.com/pg-pool/-/pg-pool-3.10.1.tgz#481047c720be2d624792100cac1816f8850d31b2" + integrity sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg== -pg-protocol@^1.9.5: - version "1.9.5" - resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.9.5.tgz#e544eff37d6ab79c26281d7c0b59ac9be4862686" - integrity sha512-DYTWtWpfd5FOro3UnAfwvhD8jh59r2ig8bPtc9H8Ds7MscE/9NYruUQWFAOuraRl29jwcT2kyMFQ3MxeaVjUhg== +pg-protocol@^1.10.3: + version "1.10.3" + resolved "https://registry.yarnpkg.com/pg-protocol/-/pg-protocol-1.10.3.tgz#ac9e4778ad3f84d0c5670583bab976ea0a34f69f" + integrity sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ== -pg-types@^2.1.0: +pg-types@2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/pg-types/-/pg-types-2.2.0.tgz#2d0250d636454f7cfa3b6ae0382fdfa8063254a3" integrity sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA== @@ -1287,26 +1348,26 @@ pg-types@^2.1.0: postgres-interval "^1.1.0" pg@^8.15.6: - version "8.15.6" - resolved "https://registry.yarnpkg.com/pg/-/pg-8.15.6.tgz#2a28e98fb6cab18b886ce58b2c184d712a94880a" - integrity sha512-yvao7YI3GdmmrslNVsZgx9PfntfWrnXwtR+K/DjI0I/sTKif4Z623um+sjVZ1hk5670B+ODjvHDAckKdjmPTsg== + version "8.16.3" + resolved "https://registry.yarnpkg.com/pg/-/pg-8.16.3.tgz#160741d0b44fdf64680e45374b06d632e86c99fd" + integrity sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw== dependencies: - pg-connection-string "^2.8.5" - pg-pool "^3.9.6" - pg-protocol "^1.9.5" - pg-types "^2.1.0" - pgpass "1.x" + pg-connection-string "^2.9.1" + pg-pool "^3.10.1" + pg-protocol "^1.10.3" + pg-types "2.2.0" + pgpass "1.0.5" optionalDependencies: - pg-cloudflare "^1.2.5" + pg-cloudflare "^1.2.7" -pgpass@1.x: +pgpass@1.0.5: version "1.0.5" resolved "https://registry.yarnpkg.com/pgpass/-/pgpass-1.0.5.tgz#9b873e4a564bb10fa7a7dbd55312728d422a223d" integrity sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug== dependencies: split2 "^4.1.0" -picomatch@^2.0.4, picomatch@^2.2.1: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -1344,17 +1405,12 @@ prettier@3.5.3: integrity sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw== prisma@^6.9.0: - version "6.9.0" - resolved "https://registry.yarnpkg.com/prisma/-/prisma-6.9.0.tgz#c8bce4fc63f0c6972f3868692e649bb163fd807d" - integrity sha512-resJAwMyZREC/I40LF6FZ6rZTnlrlrYrb63oW37Gq+U+9xHwbyMSPJjKtM7VZf3gTO86t/Oyz+YeSXr3CmAY1Q== + version "6.10.1" + resolved "https://registry.yarnpkg.com/prisma/-/prisma-6.10.1.tgz#2864034879c492359684193720e9e4b4a0bd20c9" + integrity sha512-khhlC/G49E4+uyA3T3H5PRBut486HD2bDqE2+rvkU0pwk9IAqGFacLFUyIx9Uw+W2eCtf6XGwsp+/strUwMNPw== dependencies: - "@prisma/config" "6.9.0" - "@prisma/engines" "6.9.0" - -process-nextick-args@~2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2" - integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== + "@prisma/config" "6.10.1" + "@prisma/engines" "6.10.1" proxy-addr@^2.0.7: version "2.0.7" @@ -1401,7 +1457,7 @@ raw-body@^3.0.0: iconv-lite "0.6.3" unpipe "1.0.0" -readable-stream@3, readable-stream@^3.4.0: +readable-stream@3, readable-stream@^3.0.2, readable-stream@^3.4.0: version "3.6.2" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== @@ -1410,19 +1466,6 @@ readable-stream@3, readable-stream@^3.4.0: string_decoder "^1.1.1" util-deprecate "^1.0.1" -readable-stream@^2.2.2: - version "2.3.8" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.8.tgz#91125e8042bba1b9887f49345f6277027ce8be9b" - integrity sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA== - dependencies: - core-util-is "~1.0.0" - inherits "~2.0.3" - isarray "~1.0.0" - process-nextick-args "~2.0.0" - safe-buffer "~5.1.1" - string_decoder "~1.1.1" - util-deprecate "~1.0.1" - readdirp@~3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.6.0.tgz#74a370bd857116e245b29cc97340cd431a02a6c7" @@ -1435,6 +1478,11 @@ readline-sync@^1.4.10: resolved "https://registry.yarnpkg.com/readline-sync/-/readline-sync-1.4.10.tgz#41df7fbb4b6312d673011594145705bf56d8873b" integrity sha512-gNva8/6UAe8QYepIQH/jQ2qn91Qj0B9sYjMBBs3QOB8F2CXcKgLxQaJRP76sWVRQt+QU+8fAkCbCvjjMFu7Ycw== +requires-port@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== + resolve@^1.0.0: version "1.22.10" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.10.tgz#b663e83ffb09bbf2386944736baae803029b8b39" @@ -1467,11 +1515,6 @@ safe-buffer@5.2.1, safe-buffer@^5.0.1, safe-buffer@~5.2.0: resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== -safe-buffer@~5.1.0, safe-buffer@~5.1.1: - version "5.1.2" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" - integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g== - safe-regex-test@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/safe-regex-test/-/safe-regex-test-1.1.0.tgz#7f87dfb67a3150782eaaf18583ff5d1711ac10c1" @@ -1492,9 +1535,9 @@ sax@>=0.6.0: integrity sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg== semver@^7.5.3, semver@^7.5.4: - version "7.7.1" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.1.tgz#abd5098d82b18c6c81f6074ff2647fd3e7220c9f" - integrity sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA== + version "7.7.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.7.2.tgz#67d99fdcd35cec21e6f8b87a7fd515a33f982b58" + integrity sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA== send@^1.1.0, send@^1.2.0: version "1.2.0" @@ -1610,11 +1653,16 @@ split2@^4.1.0: resolved "https://registry.yarnpkg.com/split2/-/split2-4.2.0.tgz#c9c5920904d148bab0b9f67145f245a86aadbfa4" integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== -statuses@2.0.1, statuses@^2.0.1: +statuses@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.1.tgz#55cb000ccf1d48728bd23c685a063998cf1a1b63" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +statuses@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-2.0.2.tgz#8f75eecef765b5e1cfcdc080da59409ed424e382" + integrity sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw== + stream-chain@^2.2.5: version "2.2.5" resolved "https://registry.yarnpkg.com/stream-chain/-/stream-chain-2.2.5.tgz#b30967e8f14ee033c5b9a19bbe8a2cba90ba0d09" @@ -1644,13 +1692,6 @@ string_decoder@^1.1.1: dependencies: safe-buffer "~5.2.0" -string_decoder@~1.1.1: - version "1.1.1" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" - integrity sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg== - dependencies: - safe-buffer "~5.1.0" - strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -1698,9 +1739,9 @@ swagger-parser@^10.0.3: "@apidevtools/swagger-parser" "10.0.3" swagger-ui-dist@>=5.0.0: - version "5.21.0" - resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-5.21.0.tgz#aed230fe6e294c9470217e67697d601e3bb8eb9d" - integrity sha512-E0K3AB6HvQd8yQNSMR7eE5bk+323AUxjtCz/4ZNKiahOlPhPJxqn3UPIGs00cyY/dhrTDJ61L7C/a8u6zhGrZg== + version "5.25.3" + resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-5.25.3.tgz#5eb728d9d1e481dfad2980839ab06fcbaaae6dc2" + integrity sha512-mqWJAhfl8mhVKJezwszUqRJAlrvKG/22am5xRUWzr7ya0MFaFBAAd7Nm+tD4BdKnVx7KRWkWYJMYRkFm5a8iTg== dependencies: "@scarf/scarf" "=1.4.0" @@ -1785,7 +1826,7 @@ tsconfig@^7.0.0: strip-bom "^3.0.0" strip-json-comments "^2.0.0" -type-is@^1.6.4: +type-is@^1.6.18: version "1.6.18" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.18.tgz#4e552cd05df09467dcbc4ef739de89f2cf37c131" integrity sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g== @@ -1822,12 +1863,17 @@ undici-types@~6.21.0: resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-6.21.0.tgz#691d00af3909be93a7faa13be61b3a5b50ef12cb" integrity sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ== +undici-types@~7.8.0: + version "7.8.0" + resolved "https://registry.yarnpkg.com/undici-types/-/undici-types-7.8.0.tgz#de00b85b710c54122e44fbfd911f8d70174cd294" + integrity sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw== + unpipe@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" integrity sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ== -util-deprecate@^1.0.1, util-deprecate@~1.0.1: +util-deprecate@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== @@ -1849,9 +1895,9 @@ v8-compile-cache-lib@^3.0.1: integrity sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg== validator@^13.7.0: - version "13.15.0" - resolved "https://registry.yarnpkg.com/validator/-/validator-13.15.0.tgz#2dc7ce057e7513a55585109eec29b2c8e8c1aefd" - integrity sha512-36B2ryl4+oL5QxZ3AzD0t5SsMNGvTtQHpjgFO5tbNxfXbMFkY822ktCDe1MnlqV3301QQI9SLHDNJokDI+Z9pA== + version "13.15.15" + resolved "https://registry.yarnpkg.com/validator/-/validator-13.15.15.tgz#246594be5671dc09daa35caec5689fcd18c6e7e4" + integrity sha512-BgWVbCI72aIQy937xbawcs+hrVaN/CZ2UwutgaJ36hGqRrLNM+f5LUT/YPRbo8IV/ASeFzXszezV+y2+rq3l8A== vary@^1, vary@^1.1.2: version "1.1.2" @@ -1898,7 +1944,7 @@ xmlbuilder@~11.0.0: resolved "https://registry.yarnpkg.com/xmlbuilder/-/xmlbuilder-11.0.1.tgz#be9bae1c8a046e76b31127726347d0ad7002beb3" integrity sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA== -xtend@^4.0.0: +xtend@^4.0.0, xtend@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54" integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ== @@ -1925,6 +1971,6 @@ z-schema@^5.0.1: commander "^10.0.0" zod@^3.24.4: - version "3.24.4" - resolved "https://registry.yarnpkg.com/zod/-/zod-3.24.4.tgz#e2e2cca5faaa012d76e527d0d36622e0a90c315f" - integrity sha512-OdqJE9UDRPwWsrHjLN2F8bPxvwJBK22EHLWtanu0LSYr5YqzsaaW3RMgmjwr8Rypg5k+meEJdSPXJZXE/yqOMg== + version "3.25.67" + resolved "https://registry.yarnpkg.com/zod/-/zod-3.25.67.tgz#62987e4078e2ab0f63b491ef0c4f33df24236da8" + integrity sha512-idA2YXwpCdqUSKRCACDE6ItZD9TZzy3OZMtpfLoh6oPR47lipysRrJfjzMqFxQ3uJuUPyUeWe1r9vLH33xO/Qw== diff --git a/code/db/docker-compose.yaml b/code/db/docker-compose.yaml deleted file mode 100644 index 8df3ba8..0000000 --- a/code/db/docker-compose.yaml +++ /dev/null @@ -1,33 +0,0 @@ -services: - db: - image: postgres:17 - container_name: postgres-DB - ports: - - "5432:5432" - environment: - POSTGRES_USER: ${DB_USER} - POSTGRES_PASSWORD: ${DB_PASSWORD} - POSTGRES_DB: prisma - volumes: - - pgdata:/var/lib/postgresql/data - healthcheck: - test: ["CMD", "pg_isready", "-U", "${DB_USER}"] - interval: 5s - timeout: 3s - retries: 5 - minio: - image: quay.io/minio/minio - container_name: minio - ports: - - "9000:9000" # API - - "9001:9001" # Web GUI - environment: - MINIO_ROOT_USER: ${MINIO_USER} - MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD} - command: server /data --console-address ":9001" - volumes: - - minio-data:/data - -volumes: - pgdata: - minio-data: diff --git a/code/docker/Dockerfile b/code/docker/Dockerfile new file mode 100644 index 0000000..d69dee8 --- /dev/null +++ b/code/docker/Dockerfile @@ -0,0 +1,40 @@ +# -------- Frontend Build -------- + FROM node:20 AS frontend-build + WORKDIR /app/frontend + COPY frontend/package*.json ./ + RUN yarn install + COPY frontend/ . + RUN yarn build + + # -------- Backend Build -------- + FROM node:20 AS backend-build + WORKDIR /app/backend + COPY backend/package*.json ./ + RUN yarn install + + COPY backend/prisma ./prisma + + RUN yarn prisma generate + + # Jetzt den eigentlichen Backend-Code kopieren + COPY backend/ . + + RUN yarn build + + # -------- Production Image -------- + FROM node:20 + WORKDIR /app + + # Kopiere dist, package.json, node_modules etc. + COPY --from=backend-build /app/backend/dist ./backend/dist + COPY --from=backend-build /app/backend/package*.json ./backend/ + COPY --from=backend-build /app/backend/node_modules ./backend/node_modules + COPY --from=backend-build /app/backend/prisma ./backend/prisma + + COPY --from=frontend-build /app/frontend/build ./backend/public + + WORKDIR /app/backend + + + EXPOSE 3000 + CMD ["yarn", "serve"] \ No newline at end of file diff --git a/code/db/ERP.png b/code/docker/ERP.png similarity index 100% rename from code/db/ERP.png rename to code/docker/ERP.png diff --git a/code/db/README.md b/code/docker/README.md similarity index 100% rename from code/db/README.md rename to code/docker/README.md diff --git a/code/docker/docker-compose.yaml b/code/docker/docker-compose.yaml new file mode 100644 index 0000000..b054f09 --- /dev/null +++ b/code/docker/docker-compose.yaml @@ -0,0 +1,72 @@ +name: db + +services: + # Infrastructure services + db: + image: postgres:17 + container_name: postgres-DB + ports: + - "5432:5432" + environment: + POSTGRES_USER: ${DB_USER} + POSTGRES_PASSWORD: ${DB_PASSWORD} + POSTGRES_DB: prisma + volumes: + - pgdata:/var/lib/postgresql/data + healthcheck: + test: ["CMD", "pg_isready", "-U", "${DB_USER}", "-d", "prisma"] + interval: 5s + timeout: 3s + retries: 5 + networks: + - app-network + + minio: + image: quay.io/minio/minio + container_name: minio + ports: + - "9000:9000" # API + - "9001:9001" # Web GUI + environment: + MINIO_ROOT_USER: ${MINIO_USER} + MINIO_ROOT_PASSWORD: ${MINIO_PASSWORD} + MINIO_BROWSER_REDIRECT_URL: "http://localhost:3001/minio" + command: server /data --console-address ":9001" + volumes: + - minio-data:/data + networks: + - app-network + + # Node app - only runs when the "production" profile is activated + node-app: + container_name: featherfeed-node + build: + context: .. + dockerfile: docker/Dockerfile + env_file: + - .env + environment: + - DATABASE_URL=postgresql://${DB_USER}:${DB_PASSWORD}@postgres-DB:5432/prisma + ports: + - "${PORT:-3000}:${PORT:-3000}" + networks: + - app-network + depends_on: + db: + condition: service_healthy + minio: + condition: service_started + profiles: ["production"] # Only runs when production profile is activated + command: > + sh -c " + yarn prisma migrate deploy && + yarn serve + " + +volumes: + pgdata: + minio-data: + +networks: + app-network: + name: featherfeed-network diff --git a/code/frontend/src/api/axios.ts b/code/frontend/src/api/axios.ts index 358f9da..e1a9444 100644 --- a/code/frontend/src/api/axios.ts +++ b/code/frontend/src/api/axios.ts @@ -3,8 +3,18 @@ import { refreshToken } from "./refreshToken"; const excludedUrls: string[] = ["/user/login", "/user/register"]; +const getBaseUrl: () => string = () => { + // In production builds, NODE_ENV will be "production" + if (process.env.NODE_ENV === "production") { + // Use relative path when deployed with Express backend + return "/api"; + } else { + // Use full URL in development + return "http://localhost:3001/api"; + } +}; const api = axios.create({ - baseURL: "http://localhost:3001/api", + baseURL: getBaseUrl(), withCredentials: true, }); diff --git a/code/frontend/src/components/profile/Bio.tsx b/code/frontend/src/components/profile/Bio.tsx index 24e91d7..e3599ed 100644 --- a/code/frontend/src/components/profile/Bio.tsx +++ b/code/frontend/src/components/profile/Bio.tsx @@ -8,7 +8,15 @@ import EditSquareIcon from "@mui/icons-material/EditSquare"; import ButtonPrimary from "../buttons/buttonRotkehlchen/ButtonRotkehlchen"; import api from "../../api/axios"; -export default function BioTextField({ ownAccount, bioText, setBio } : { ownAccount: boolean, bioText: string | undefined, setBio: (bio: string) => void }) { +export default function BioTextField({ + ownAccount, + bioText, + setBio, +}: { + ownAccount: boolean; + bioText: string | undefined; + setBio: (bio: string) => void; +}) { const [oldBio, setOldbio] = useState(bioText || ""); const [editMode, setEditable] = useState(false); @@ -31,11 +39,11 @@ export default function BioTextField({ ownAccount, bioText, setBio } : { ownAcco } catch (error) { console.error("Error saving bio: ", error); } - } + }; const handleChange = (event: React.ChangeEvent) => { setBio(event.target.value); - } + }; return ( diff --git a/code/frontend/src/components/profile/bio.css b/code/frontend/src/components/profile/bio.css index e3c96ee..079b61c 100644 --- a/code/frontend/src/components/profile/bio.css +++ b/code/frontend/src/components/profile/bio.css @@ -1,35 +1,41 @@ .bio-input { - margin: 0.5rem; + margin: 0.5rem; } -.css-53g0n7-MuiButtonBase-root-MuiIconButton-root { - justify-content: end; +/* Wichtiger: Verwende wichtige Basis-Selektoren, die sich nicht ändern */ +.bio-input.MuiTextField-root .MuiOutlinedInput-root { + color: var(--Rotkehlchen-gray) !important; + background-color: transparent !important; /* Expliziter Hintergrund */ } -/* Root class for the input field */ -.bio-input .MuiOutlinedInput-root { - color: var(--Rotkehlchen-gray); +/* Für Textfarbe innerhalb des Inputs */ +.bio-input.MuiTextField-root .MuiOutlinedInput-input { + color: var(--Rotkehlchen-gray) !important; + -webkit-text-fill-color: var(--Rotkehlchen-gray) !important; } -/* Class for the border around the input field */ -.bio-input .MuiOutlinedInput-notchedOutline { - border-color: var(--Rotkehlchen-brown-light); + +/* Rahmen */ +.bio-input.MuiTextField-root .MuiOutlinedInput-notchedOutline { + border-color: var(--Rotkehlchen-brown-light) !important; } -/* Class for the label of the input field */ -.bio-input .MuiInputLabel-outlined { - color: var(--Rotkehlchen-brown-light); + +/* Label */ +.bio-input.MuiTextField-root .MuiInputLabel-root { + color: var(--Rotkehlchen-brown-light) !important; } -/* Class for the border in focused state */ -.bio-input .Mui-focused .MuiOutlinedInput-notchedOutline { - border-color: var(--Rotkehlchen-yellow-default); + +/* Fokus-Zustand */ +.bio-input.MuiTextField-root .Mui-focused .MuiOutlinedInput-notchedOutline { + border-color: var(--Rotkehlchen-yellow-default) !important; } -/* Disabled input field text and border color */ -.bio-input .css-w4nesw-MuiInputBase-input-MuiOutlinedInput-input.Mui-disabled { - -webkit-text-fill-color: var(--Rotkehlchen-gray); + +/* Deaktivierter Zustand */ +.bio-input.MuiTextField-root .Mui-disabled .MuiOutlinedInput-input { + -webkit-text-fill-color: var(--Rotkehlchen-gray) !important; } -.bio-input - .MuiInputBase-root.MuiOutlinedInput-root.Mui-disabled - .MuiOutlinedInput-notchedOutline { - border-color: transparent; + +.bio-input.MuiTextField-root .Mui-disabled .MuiOutlinedInput-notchedOutline { + border-color: transparent !important; } @media only screen and (min-width: 768px) { @@ -37,12 +43,13 @@ width: 100%; margin-bottom: 1rem; } - .bio-input .MuiInputLabel-outlined { - font-size: 18px; + + .bio-input.MuiTextField-root .MuiInputLabel-root { + font-size: 18px !important; } - .bio-input .MuiOutlinedInput-input { - font-size: 18px; - padding: 10px; + + .bio-input.MuiTextField-root .MuiOutlinedInput-input { + font-size: 18px !important; + padding: 10px !important; } - -} \ No newline at end of file +} diff --git a/code/frontend/src/pages/404Page/NotFoundPage.tsx b/code/frontend/src/pages/404Page/NotFoundPage.tsx index cc5dd45..54239ee 100644 --- a/code/frontend/src/pages/404Page/NotFoundPage.tsx +++ b/code/frontend/src/pages/404Page/NotFoundPage.tsx @@ -75,7 +75,6 @@ export const NotFound = () => { }, []); useEffect(() => { - let lastBlockTime = Date.now(); let animationId: number; function loop() { @@ -87,7 +86,7 @@ export const NotFound = () => { velocityRef.current += GRAVITY; birdPosRef.current.y += velocityRef.current; - setRotation(Math.max(Math.min(velocityRef.current * 2, 90), -15)); + setRotation(Math.max(Math.min(velocityRef.current * 4, 90), -15)); textPosRef.current -= speedRef.current; setTextPos(textPosRef.current); diff --git a/code/frontend/src/pages/profile.css b/code/frontend/src/pages/profile.css index 5d9385e..f1e3662 100644 --- a/code/frontend/src/pages/profile.css +++ b/code/frontend/src/pages/profile.css @@ -58,3 +58,20 @@ } } +.MuiImageListItem-root { + height: auto !important; + width: auto !important; +} + +.MuiImageListItem-img { + height: 5rem !important; + width: 5rem !important; + object-fit: cover !important; +} + +@media only screen and (min-width: 768px) { + .MuiImageListItem-img { + height: 15rem !important; + width: 15rem !important; + } +}