From 9e6276ace9629655bf32678b56790d06b45f18e4 Mon Sep 17 00:00:00 2001 From: anibilag Date: Mon, 17 Feb 2025 23:04:19 +0300 Subject: [PATCH] =?UTF-8?q?=D0=A0=D0=B5=D0=B0=D0=BB=D0=B8=D0=B7=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=B0=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82=D0=B0?= =?UTF-8?q?=20=D1=81=20=D1=81=D1=82=D0=B0=D1=82=D1=8C=D1=8F=D0=BC=D0=B8=20?= =?UTF-8?q?-=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D0=B8=D0=B5,=20=D1=80?= =?UTF-8?q?=D0=B5=D0=B4=D0=B0=D0=BA=D1=82=D0=B8=D1=80=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../migration.sql | 10 ++++ .../migration.sql | 11 +++++ prisma/schema.prisma | 9 +--- src/routes/articles/controllers/crud.ts | 30 +++++------- src/routes/articles/controllers/list.ts | 16 ++++--- src/routes/articles/controllers/search.ts | 1 + src/types/auth.ts | 18 ++++++-- src/types/index.ts | 15 +++--- src/utils/permissions.ts | 46 +++++++++++++------ 9 files changed, 98 insertions(+), 58 deletions(-) create mode 100644 prisma/migrations/20250210171519_change_city_type/migration.sql create mode 100644 prisma/migrations/20250210194222_change_category_type/migration.sql diff --git a/prisma/migrations/20250210171519_change_city_type/migration.sql b/prisma/migrations/20250210171519_change_city_type/migration.sql new file mode 100644 index 0000000..9436db0 --- /dev/null +++ b/prisma/migrations/20250210171519_change_city_type/migration.sql @@ -0,0 +1,10 @@ +/* + Warnings: + + - You are about to drop the column `city` on the `Article` table. All the data in the column will be lost. + - Added the required column `cityId` to the `Article` table without a default value. This is not possible if the table is not empty. + +*/ +-- AlterTable +ALTER TABLE "Article" DROP COLUMN "city", +ADD COLUMN "cityId" INTEGER NOT NULL; diff --git a/prisma/migrations/20250210194222_change_category_type/migration.sql b/prisma/migrations/20250210194222_change_category_type/migration.sql new file mode 100644 index 0000000..366ee8a --- /dev/null +++ b/prisma/migrations/20250210194222_change_category_type/migration.sql @@ -0,0 +1,11 @@ +/* + Warnings: + + - You are about to drop the `Category` table. If the table is not empty, all the data it contains will be lost. + +*/ +-- DropForeignKey +ALTER TABLE "Article" DROP CONSTRAINT "Article_categoryId_fkey"; + +-- DropTable +DROP TABLE "Category"; diff --git a/prisma/schema.prisma b/prisma/schema.prisma index 96bf3dc..fde9ae4 100644 --- a/prisma/schema.prisma +++ b/prisma/schema.prisma @@ -25,9 +25,8 @@ model Article { title String excerpt String content String - category Category @relation(fields: [categoryId], references: [id]) categoryId Int - city String + cityId Int coverImage String readTime Int likes Int @default(0) @@ -38,12 +37,6 @@ model Article { gallery GalleryImage[] } -model Category { - id Int @id - name String @unique - articles Article[] -} - model GalleryImage { id String @id @default(uuid()) url String diff --git a/src/routes/articles/controllers/crud.ts b/src/routes/articles/controllers/crud.ts index bfa16e6..852ea2a 100644 --- a/src/routes/articles/controllers/crud.ts +++ b/src/routes/articles/controllers/crud.ts @@ -9,11 +9,11 @@ export async function getArticle(req: Request, res: Response) : Promise { const article = await prisma.article.findUnique({ where: { id: req.params.id }, include: { - category: true, author: { select: { id: true, displayName: true, + avatarUrl: true, email: true } } @@ -35,7 +35,7 @@ export async function getArticle(req: Request, res: Response) : Promise { export async function createArticle(req: AuthRequest, res: Response) : Promise { try { - const { title, excerpt, content, categoryId, city, coverImage, readTime } = req.body; + const { title, excerpt, content, categoryId, cityId, coverImage, readTime } = req.body; if (!req.user) { logger.warn('Unauthorized article creation attempt'); @@ -43,18 +43,14 @@ export async function createArticle(req: AuthRequest, res: Response) : Promise 8) { logger.warn(`Invalid category ID: ${categoryId}`); res.status(400).json({ error: 'Invalid category' }); return } if (!checkPermission(req.user, categoryId, 'create')) { - logger.warn(`Permission denied for user ${req.user.id} to create article in category ${category.name}`); + logger.warn(`Permission denied for user ${req.user.id} to create article in category ${categoryId}`); res.status(403).json({ error: 'Permission denied' }); return } @@ -65,13 +61,12 @@ export async function createArticle(req: AuthRequest, res: Response) : Promise { try { - const { title, excerpt, content, category, city, coverImage, readTime } = req.body; + const { title, excerpt, content, categoryId, cityId, coverImage, readTime } = req.body; if (!req.user) { res.status(401).json({ error: 'Пользователь не вошел в систему' }); @@ -100,8 +95,7 @@ export async function updateArticle(req: AuthRequest, res: Response) : Promise = { 'Film': 1, 'Theater': 2, @@ -48,3 +50,4 @@ export const CategoryMap: Record = { 'Anniversaries': 7, 'Memory': 8, }; +*/ diff --git a/src/utils/permissions.ts b/src/utils/permissions.ts index 9a19386..fb84aff 100644 --- a/src/utils/permissions.ts +++ b/src/utils/permissions.ts @@ -1,30 +1,46 @@ -import { Category, City } from '../types'; -import { User } from '../types/auth'; +import {PermissionAction, User} from '../types/auth'; +/* export const checkPermission = ( user: User, - category: Category, - action: 'create' | 'edit' | 'delete' + categoryId: string, + action: PermissionAction ): boolean => { if (user.permissions.isAdmin) return true; - return !!user.permissions.categories[category.name]?.[action]; + return !!user.permissions.categories?[categoryId]?.[action]; +}; +*/ + +export const checkPermission = ( + user: User, + categoryId: string, + action: PermissionAction +): boolean => { + // Если пользователь админ — ему разрешено всё + if (user.permissions.isAdmin) return true; + + // Проверяем, есть ли такая категория в permissions + const categoryPermissions = user.permissions.categories[categoryId]; + + // Если категория отсутствует или в ней нет действия — запрет + return categoryPermissions ? categoryPermissions[action] : false; }; -export const checkCityAccess = (user: User, city: City): boolean => { +export const checkCityAccess = (user: User, cityId: number): boolean => { if (user.permissions.isAdmin) return true; - return user.permissions.cities.includes(city); + return user.permissions.cities.includes(cityId); }; export const getDefaultPermissions = () => ({ categories: { - Film: { create: false, edit: false, delete: false }, - Theater: { create: false, edit: false, delete: false }, - Music: { create: false, edit: false, delete: false }, - Sports: { create: false, edit: false, delete: false }, - Art: { create: false, edit: false, delete: false }, - Legends: { create: false, edit: false, delete: false }, - Anniversaries: { create: false, edit: false, delete: false }, - Memory: { create: false, edit: false, delete: false } + 1: { create: false, edit: false, delete: false }, + 2: { create: false, edit: false, delete: false }, + 3: { create: false, edit: false, delete: false }, + 4: { create: false, edit: false, delete: false }, + 5: { create: false, edit: false, delete: false }, + 6: { create: false, edit: false, delete: false }, + 7: { create: false, edit: false, delete: false }, + 8: { create: false, edit: false, delete: false } }, cities: [], isAdmin: false