From 6d0aef416301ca55a2e6d94a9febb2544eb66133 Mon Sep 17 00:00:00 2001 From: AI Assistant Date: Fri, 16 Jan 2026 18:00:48 +0700 Subject: [PATCH] feat: enhance admin security, add img delete, optimize docker --- Dockerfile | 3 ++- package-lock.json | 5 +---- package.json | 3 ++- src/app/actions.ts | 10 ++++++++++ src/features/inventory/ItemDetailDialog.tsx | 18 +++++++++++++++++- 5 files changed, 32 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index 4a70eb7..132226f 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,8 @@ WORKDIR /app # Install dependencies based on the preferred package manager COPY package.json package-lock.json* ./ -RUN npm install --ignore-scripts +COPY prisma ./prisma +RUN npm install # Rebuild the source code only when needed FROM base AS builder diff --git a/package-lock.json b/package-lock.json index 0d5f545..3d7db6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -29,6 +29,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "react-hook-form": "^7.71.1", + "sharp": "^0.34.5", "tailwind-merge": "^3.4.0", "webpack": "^5.104.1", "zod": "^4.3.5", @@ -2480,7 +2481,6 @@ "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.0.0.tgz", "integrity": "sha512-A5P/LfWGFSl6nsckYtjw9da+19jB8hkJ6ACTGcDfEJ0aE+l2n2El7dsVM7UVHZQ9s2lmYMWlrS21YLy2IR1LUw==", "license": "MIT", - "optional": true, "engines": { "node": ">=18" } @@ -6714,7 +6714,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "devOptional": true, "license": "Apache-2.0", "engines": { "node": ">=8" @@ -10859,7 +10858,6 @@ "integrity": "sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==", "hasInstallScript": true, "license": "Apache-2.0", - "optional": true, "dependencies": { "@img/colour": "^1.0.0", "detect-libc": "^2.1.2", @@ -10903,7 +10901,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "license": "ISC", - "optional": true, "bin": { "semver": "bin/semver.js" }, diff --git a/package.json b/package.json index 5e4c835..ff3cedc 100644 --- a/package.json +++ b/package.json @@ -33,6 +33,7 @@ "react": "19.2.3", "react-dom": "19.2.3", "react-hook-form": "^7.71.1", + "sharp": "^0.34.5", "tailwind-merge": "^3.4.0", "webpack": "^5.104.1", "zod": "^4.3.5", @@ -56,4 +57,4 @@ "typescript": "^5", "vitest": "^4.0.17" } -} \ No newline at end of file +} diff --git a/src/app/actions.ts b/src/app/actions.ts index 0b3e0bc..ab343d0 100644 --- a/src/app/actions.ts +++ b/src/app/actions.ts @@ -324,6 +324,16 @@ export async function loginUser(username: string, pass: string) { } } + // Security Check: If logging in as 'admin' with default password, BLOCK it if other users exist + if (username === 'admin' && pass === 'admin') { + const otherUsersCount = await prisma.user.count({ + where: { username: { not: 'admin' } } + }); + if (otherUsersCount > 0) { + return { success: false, error: "Tài khoản admin mặc định đã bị vô hiệu hóa vì hệ thống đã có người dùng mới." }; + } + } + const user = await prisma.user.findUnique({ where: { username } }); if (!user) return { success: false, error: "Người dùng không tồn tại" }; diff --git a/src/features/inventory/ItemDetailDialog.tsx b/src/features/inventory/ItemDetailDialog.tsx index f0474a2..27e62d0 100644 --- a/src/features/inventory/ItemDetailDialog.tsx +++ b/src/features/inventory/ItemDetailDialog.tsx @@ -275,7 +275,23 @@ function EditMode({ item, locations, onCancel, onClose }: { item: any, locations
- +
+ + {imgPreview && ( + + )} +