diff --git a/src/components/supplier-orders/supplier-orders-tabs.tsx b/src/components/supplier-orders/supplier-orders-tabs.tsx index b8d28ef..fa3bfa1 100644 --- a/src/components/supplier-orders/supplier-orders-tabs.tsx +++ b/src/components/supplier-orders/supplier-orders-tabs.tsx @@ -115,7 +115,7 @@ interface SupplyOrder { } export function SupplierOrdersTabs() { - const { user } = useAuth() + const { user: _user } = useAuth() const [activeTab, setActiveTab] = useState('new') const [searchQuery, setSearchQuery] = useState('') const [dateFilter, setDateFilter] = useState('') diff --git a/src/components/supplies/multilevel-supplies-table.tsx b/src/components/supplies/multilevel-supplies-table.tsx index 273562c..36f98c5 100644 --- a/src/components/supplies/multilevel-supplies-table.tsx +++ b/src/components/supplies/multilevel-supplies-table.tsx @@ -184,7 +184,7 @@ const TableCell = ({ // ActionButtons компонент для кнопок действий поставщика function ActionButtons({ supplyId, - onSupplyAction + onSupplyAction, }: { supplyId: string onSupplyAction?: (supplyId: string, action: string) => void @@ -383,7 +383,7 @@ export function MultiLevelSuppliesTable({ newValues[supply.id] = { volume: isVolumePending ? (prev[supply.id]?.volume ?? '') : (supply.volume?.toString() ?? ''), - packages: isPackagesPending ? (prev[supply.id]?.packages ?? '') : (supply.packagesCount?.toString() ?? '') + packages: isPackagesPending ? (prev[supply.id]?.packages ?? '') : (supply.packagesCount?.toString() ?? ''), } }) @@ -860,8 +860,8 @@ export function MultiLevelSuppliesTable({ ...prev, [supply.id]: { ...prev[supply.id], - volume: value - } + volume: value, + }, })) // Вызываем обработчик с преобразованным значением const numValue = value === '' ? null : parseFloat(value) @@ -893,8 +893,8 @@ export function MultiLevelSuppliesTable({ ...prev, [supply.id]: { ...prev[supply.id], - packages: value - } + packages: value, + }, })) // Вызываем обработчик с преобразованным значением const numValue = value === '' ? null : parseInt(value) diff --git a/src/graphql/resolvers.ts b/src/graphql/resolvers.ts index a34a012..0db4fcb 100644 --- a/src/graphql/resolvers.ts +++ b/src/graphql/resolvers.ts @@ -24,7 +24,7 @@ function createSecureContextWithOrgData(context: Context, currentUser: any) { ...context.user, organizationType: currentUser.organization.type, organizationId: currentUser.organization.id, - } + }, } } import { ParticipantIsolation } from './security/participant-isolation' @@ -7287,7 +7287,7 @@ export const resolvers = { updateSupplyParameters: async ( _: unknown, args: { id: string; volume?: number; packagesCount?: number }, - context: GraphQLContext + context: GraphQLContext, ) => { try { // Проверка аутентификации @@ -7301,7 +7301,7 @@ export const resolvers = { // Найти поставку и проверить права доступа const supply = await prisma.supplyOrder.findUnique({ where: { id: args.id }, - include: { partner: true } + include: { partner: true }, }) if (!supply) { @@ -7623,7 +7623,7 @@ export const resolvers = { }, }) - console.warn(`[DEBUG] updatedOrder structure:`, { + console.warn('[DEBUG] updatedOrder structure:', { id: updatedOrder.id, itemsCount: updatedOrder.items?.length || 0, firstItem: updatedOrder.items?.[0] ? { @@ -7640,7 +7640,7 @@ export const resolvers = { const filteredOrder = SupplyDataFilter.filterSupplyOrder(updatedOrder, securityContextWithOrgType) console.warn(`[DEBUG] Заказ ${args.id} успешно обновлен до статуса: ${updatedOrder.status}`) - console.warn(`[DEBUG] filteredOrder:`, { + console.warn('[DEBUG] filteredOrder:', { hasData: !!filteredOrder.data, dataId: filteredOrder.data?.id, dataKeys: Object.keys(filteredOrder.data || {}), diff --git a/src/graphql/resolvers/index.ts b/src/graphql/resolvers/index.ts index 3b5b9ec..c3fa26a 100644 --- a/src/graphql/resolvers/index.ts +++ b/src/graphql/resolvers/index.ts @@ -5,9 +5,9 @@ import { authResolvers } from './auth' import { employeeResolvers } from './employees' import { logisticsResolvers } from './logistics' import { referralResolvers } from './referrals' -import { suppliesResolvers } from './supplies' -import { secureSuppliesResolvers } from './secure-supplies' import { integrateSecurityWithExistingResolvers } from './secure-integration' +import { secureSuppliesResolvers } from './secure-supplies' +import { suppliesResolvers } from './supplies' // Типы для резолверов interface ResolverObject { diff --git a/src/graphql/resolvers/secure-integration.ts b/src/graphql/resolvers/secure-integration.ts index 06c9401..28ecc55 100644 --- a/src/graphql/resolvers/secure-integration.ts +++ b/src/graphql/resolvers/secure-integration.ts @@ -5,8 +5,8 @@ * к существующим резолверам без их полной переписки */ -import { wrapResolversWithSecurity, listSecuredResolvers } from '../security' import { SecurityLogger } from '../../lib/security-logger' +import { wrapResolversWithSecurity, listSecuredResolvers } from '../security' /** * Пример интеграции с существующими резолверами @@ -49,7 +49,7 @@ export const secureSupplyOrderResolver = { SupplyDataFilter, ParticipantIsolation, CommercialDataAudit, - FEATURE_FLAGS + FEATURE_FLAGS, } = await import('../security') // Проверяем включена ли система безопасности @@ -115,10 +115,10 @@ export const secureSupplyOrderResolver = { recipe: { services: [{ id: 'service-1', name: 'Test Service', price: 100 }], fulfillmentConsumables: [ - { id: 'consumable-1', name: 'Test Consumable', quantity: 1, pricePerUnit: 50, price: 50 } + { id: 'consumable-1', name: 'Test Consumable', quantity: 1, pricePerUnit: 50, price: 50 }, ], sellerConsumables: [ - { id: 'consumable-2', name: 'Seller Consumable', quantity: 2, pricePerUnit: 25, price: 50 } + { id: 'consumable-2', name: 'Seller Consumable', quantity: 2, pricePerUnit: 25, price: 50 }, ], }, }, diff --git a/src/graphql/resolvers/secure-supplies.ts b/src/graphql/resolvers/secure-supplies.ts index 37068f7..fda8068 100644 --- a/src/graphql/resolvers/secure-supplies.ts +++ b/src/graphql/resolvers/secure-supplies.ts @@ -5,20 +5,20 @@ * для обеспечения ролевого доступа и защиты коммерческой информации */ -import { GraphQLError } from 'graphql' import { OrganizationType } from '@prisma/client' +import { GraphQLError } from 'graphql' import { prisma } from '@/lib/prisma' import { notifyMany, notifyOrganization } from '@/lib/realtime' -import { createSecureResolver, SecurityHelpers } from '../security' -import { SupplyDataFilter } from '../security/supply-data-filter' -import { ParticipantIsolation } from '../security/participant-isolation' -import { CommercialDataAudit } from '../security/commercial-data-audit' -import { RecipeAccessControl } from '../security/recipe-access-control' import { SecurityLogger } from '../../lib/security-logger' - import type { Context } from '../context' +import { createSecureResolver, SecurityHelpers } from '../security' +import { CommercialDataAudit } from '../security/commercial-data-audit' +import { ParticipantIsolation } from '../security/participant-isolation' +import { RecipeAccessControl } from '../security/recipe-access-control' +import { SupplyDataFilter } from '../security/supply-data-filter' + /** * Интерфейс аргументов для получения поставок diff --git a/src/graphql/security/__tests__/fulfillment-security-tests.ts b/src/graphql/security/__tests__/fulfillment-security-tests.ts index ba12af3..7bd96b7 100644 --- a/src/graphql/security/__tests__/fulfillment-security-tests.ts +++ b/src/graphql/security/__tests__/fulfillment-security-tests.ts @@ -8,9 +8,10 @@ import { PrismaClient } from '@prisma/client' import { GraphQLError } from 'graphql' -import { SupplyDataFilter } from '../supply-data-filter' -import { ParticipantIsolation } from '../participant-isolation' import { CommercialDataAudit } from '../commercial-data-audit' +import { ParticipantIsolation } from '../participant-isolation' +import { SupplyDataFilter } from '../supply-data-filter' + import { SecurityTestFramework, TestRole, VulnerabilitySeverity, SecurityTestResult } from './security-test-framework' export class FulfillmentSecurityTests extends SecurityTestFramework { @@ -254,7 +255,7 @@ export class FulfillmentSecurityTests extends SecurityTestFramework { // Ищем заказ, назначенный этому фулфилменту const assignedOrder = this.getTestData().supplyOrders.find(order => - order.fulfillmentCenterId === fulfillmentUser.organizationId + order.fulfillmentCenterId === fulfillmentUser.organizationId, ) if (!assignedOrder) { @@ -319,7 +320,7 @@ export class FulfillmentSecurityTests extends SecurityTestFramework { // Ищем заказ НЕ назначенный этому фулфилменту const unassignedOrder = this.getTestData().supplyOrders.find(order => - order.fulfillmentCenterId !== fulfillmentUser.organizationId + order.fulfillmentCenterId !== fulfillmentUser.organizationId, ) if (!unassignedOrder) { @@ -406,7 +407,7 @@ export class FulfillmentSecurityTests extends SecurityTestFramework { const mockContext = this.createMockContext(fulfillmentUser) const assignedOrder = this.getTestData().supplyOrders.find(order => - order.fulfillmentCenterId === fulfillmentUser.organizationId + order.fulfillmentCenterId === fulfillmentUser.organizationId, ) if (!assignedOrder) { @@ -462,7 +463,7 @@ export class FulfillmentSecurityTests extends SecurityTestFramework { const mockContext = this.createMockContext(fulfillmentUser) const assignedOrder = this.getTestData().supplyOrders.find(order => - order.fulfillmentCenterId === fulfillmentUser.organizationId + order.fulfillmentCenterId === fulfillmentUser.organizationId, ) if (!assignedOrder) { diff --git a/src/graphql/security/__tests__/logist-security-tests.ts b/src/graphql/security/__tests__/logist-security-tests.ts index 6e1c951..8515040 100644 --- a/src/graphql/security/__tests__/logist-security-tests.ts +++ b/src/graphql/security/__tests__/logist-security-tests.ts @@ -8,9 +8,10 @@ import { PrismaClient } from '@prisma/client' import { GraphQLError } from 'graphql' -import { SupplyDataFilter } from '../supply-data-filter' -import { ParticipantIsolation } from '../participant-isolation' import { CommercialDataAudit } from '../commercial-data-audit' +import { ParticipantIsolation } from '../participant-isolation' +import { SupplyDataFilter } from '../supply-data-filter' + import { SecurityTestFramework, TestRole, VulnerabilitySeverity, SecurityTestResult } from './security-test-framework' export class LogistSecurityTests extends SecurityTestFramework { @@ -254,7 +255,7 @@ export class LogistSecurityTests extends SecurityTestFramework { // Ищем заказ, назначенный этому логисту const assignedOrder = this.getTestData().supplyOrders.find(order => - order.logisticsPartnerId === logistUser.organizationId + order.logisticsPartnerId === logistUser.organizationId, ) if (!assignedOrder) { @@ -321,7 +322,7 @@ export class LogistSecurityTests extends SecurityTestFramework { // Ищем заказ НЕ назначенный этому логисту const unassignedOrder = this.getTestData().supplyOrders.find(order => - order.logisticsPartnerId !== logistUser.organizationId + order.logisticsPartnerId !== logistUser.organizationId, ) if (!unassignedOrder) { @@ -413,7 +414,7 @@ export class LogistSecurityTests extends SecurityTestFramework { const mockContext = this.createMockContext(logistUser) const assignedOrder = this.getTestData().supplyOrders.find(order => - order.logisticsPartnerId === logistUser.organizationId + order.logisticsPartnerId === logistUser.organizationId, ) if (!assignedOrder) { @@ -472,7 +473,7 @@ export class LogistSecurityTests extends SecurityTestFramework { const assignedOrder = this.getTestData().supplyOrders.find(order => order.logisticsPartnerId === logistUser.organizationId && - order.items.some(item => item.recipe && Object.keys(item.recipe).length > 0) + order.items.some(item => item.recipe && Object.keys(item.recipe).length > 0), ) if (!assignedOrder) { @@ -526,7 +527,7 @@ export class LogistSecurityTests extends SecurityTestFramework { const mockContext = this.createMockContext(logistUser) const assignedOrder = this.getTestData().supplyOrders.find(order => - order.logisticsPartnerId === logistUser.organizationId + order.logisticsPartnerId === logistUser.organizationId, ) if (!assignedOrder) { diff --git a/src/graphql/security/__tests__/security-performance-tests.ts b/src/graphql/security/__tests__/security-performance-tests.ts index a1d0889..759eb63 100644 --- a/src/graphql/security/__tests__/security-performance-tests.ts +++ b/src/graphql/security/__tests__/security-performance-tests.ts @@ -5,13 +5,15 @@ * тестирование нагрузки, латентности и throughput всех компонентов */ -import { PrismaClient } from '@prisma/client' import { performance } from 'perf_hooks' -import { SupplyDataFilter } from '../supply-data-filter' +import { PrismaClient } from '@prisma/client' + +import { AdvancedAuditReporting } from '../advanced-audit-reporting' import { AutomatedThreatDetection } from '../automated-threat-detection' import { RealTimeSecurityAlerts } from '../real-time-security-alerts' -import { AdvancedAuditReporting } from '../advanced-audit-reporting' +import { SupplyDataFilter } from '../supply-data-filter' + import { SecurityTestFramework, TestRole, VulnerabilitySeverity, SecurityTestResult } from './security-test-framework' export class SecurityPerformanceTests extends SecurityTestFramework { @@ -688,7 +690,7 @@ export class SecurityPerformanceTests extends SecurityTestFramework { id: `test-user-perf-${Math.random().toString(36).substr(2, 9)}`, organizationId: `org-perf-${Math.random().toString(36).substr(2, 9)}`, organizationType: role, - email: `test.perf@example.com`, + email: 'test.perf@example.com', } } @@ -712,8 +714,8 @@ export class SecurityPerformanceTests extends SecurityTestFramework { return { id: `order-perf-${Math.random().toString(36).substr(2, 9)}`, organizationId: `seller-org-${Math.random().toString(36).substr(2, 9)}`, - fulfillmentCenterId: `fulfillment-org-001`, - logisticsPartnerId: `logist-org-001`, + fulfillmentCenterId: 'fulfillment-org-001', + logisticsPartnerId: 'logist-org-001', productPrice: 1000 + Math.random() * 1000, fulfillmentServicePrice: 200 + Math.random() * 200, logisticsPrice: 100 + Math.random() * 100, diff --git a/src/graphql/security/__tests__/security-test-framework.ts b/src/graphql/security/__tests__/security-test-framework.ts index 8900336..ab0bda3 100644 --- a/src/graphql/security/__tests__/security-test-framework.ts +++ b/src/graphql/security/__tests__/security-test-framework.ts @@ -11,12 +11,12 @@ import { PrismaClient } from '@prisma/client' import { GraphQLError } from 'graphql' -import { SupplyDataFilter } from '../supply-data-filter' -import { ParticipantIsolation } from '../participant-isolation' -import { CommercialDataAudit } from '../commercial-data-audit' -import { RealTimeSecurityAlerts } from '../real-time-security-alerts' -import { AutomatedThreatDetection } from '../automated-threat-detection' import { SecurityLogger } from '../../../lib/security-logger' +import { AutomatedThreatDetection } from '../automated-threat-detection' +import { CommercialDataAudit } from '../commercial-data-audit' +import { ParticipantIsolation } from '../participant-isolation' +import { RealTimeSecurityAlerts } from '../real-time-security-alerts' +import { SupplyDataFilter } from '../supply-data-filter' /** * Типы тестов безопасности @@ -704,7 +704,7 @@ export class SecurityTestFramework { */ getCriticalVulnerabilities(): SecurityTestResult[] { return this.testResults.filter(result => - !result.passed && result.severity === VulnerabilitySeverity.CRITICAL + !result.passed && result.severity === VulnerabilitySeverity.CRITICAL, ) } } \ No newline at end of file diff --git a/src/graphql/security/__tests__/seller-security-tests.ts b/src/graphql/security/__tests__/seller-security-tests.ts index da2c20f..158b6e3 100644 --- a/src/graphql/security/__tests__/seller-security-tests.ts +++ b/src/graphql/security/__tests__/seller-security-tests.ts @@ -8,9 +8,10 @@ import { PrismaClient } from '@prisma/client' import { GraphQLError } from 'graphql' -import { SupplyDataFilter } from '../supply-data-filter' -import { ParticipantIsolation } from '../participant-isolation' import { CommercialDataAudit } from '../commercial-data-audit' +import { ParticipantIsolation } from '../participant-isolation' +import { SupplyDataFilter } from '../supply-data-filter' + import { SecurityTestFramework, TestRole, VulnerabilitySeverity, SecurityTestResult } from './security-test-framework' export class SellerSecurityTests extends SecurityTestFramework { @@ -234,7 +235,7 @@ export class SellerSecurityTests extends SecurityTestFramework { // Симулируем запрос на получение собственных заказов const ownOrder = this.getTestData().supplyOrders.find( - order => order.organizationId === sellerUser.organizationId + order => order.organizationId === sellerUser.organizationId, ) if (!ownOrder) { @@ -290,7 +291,7 @@ export class SellerSecurityTests extends SecurityTestFramework { // Найдем заказ другого селлера const otherSellerOrder = this.getTestData().supplyOrders.find( - order => order.organizationId !== sellerUser.organizationId + order => order.organizationId !== sellerUser.organizationId, ) if (!otherSellerOrder) { @@ -347,7 +348,7 @@ export class SellerSecurityTests extends SecurityTestFramework { const hasAdminPermissions = sellerUser.permissions.some(permission => permission.includes('ADMIN') || permission.includes('DELETE') || - permission.includes('MANAGE_USERS') + permission.includes('MANAGE_USERS'), ) // Также проверяем, что SELLER не может выполнять административные GraphQL запросы @@ -393,7 +394,7 @@ export class SellerSecurityTests extends SecurityTestFramework { // Попытка изменить заказ другой организации const otherOrgOrder = this.getTestData().supplyOrders.find( - order => order.organizationId !== sellerUser.organizationId + order => order.organizationId !== sellerUser.organizationId, ) if (!otherOrgOrder) { @@ -405,7 +406,7 @@ export class SellerSecurityTests extends SecurityTestFramework { this.prisma, sellerUser.organizationId, otherOrgOrder.organizationId, - mockContext + mockContext, ) return { @@ -458,7 +459,7 @@ export class SellerSecurityTests extends SecurityTestFramework { const mockContext = this.createMockContext(sellerUser) const ownOrder = this.getTestData().supplyOrders.find( - order => order.organizationId === sellerUser.organizationId + order => order.organizationId === sellerUser.organizationId, ) if (!ownOrder) { @@ -533,7 +534,7 @@ export class SellerSecurityTests extends SecurityTestFramework { const mockContext = this.createMockContext(sellerUser) const competitorOrder = this.getTestData().supplyOrders.find( - order => order.organizationId !== sellerUser.organizationId + order => order.organizationId !== sellerUser.organizationId, ) if (!competitorOrder) { @@ -631,7 +632,7 @@ export class SellerSecurityTests extends SecurityTestFramework { organizationType: role, email: 'test.seller@example.com', permissions: ['READ_OWN_SUPPLIES', 'CREATE_SUPPLY_ORDER'], - }] + }], ]) return testUsers.get(role) @@ -703,7 +704,7 @@ export class SellerSecurityTests extends SecurityTestFramework { return user.permissions.some((perm: string) => perm.includes('ADMIN') || perm.includes('MANAGE') || - perm.includes('DELETE_ALL') + perm.includes('DELETE_ALL'), ) } diff --git a/src/graphql/security/__tests__/threat-detection-integration-tests.ts b/src/graphql/security/__tests__/threat-detection-integration-tests.ts index bdb6634..ae40f51 100644 --- a/src/graphql/security/__tests__/threat-detection-integration-tests.ts +++ b/src/graphql/security/__tests__/threat-detection-integration-tests.ts @@ -5,15 +5,18 @@ * тестирование взаимодействия между компонентами, real-time alerts и ML модели */ -import { PrismaClient } from '@prisma/client' import { EventEmitter } from 'events' -import { AutomatedThreatDetection } from '../automated-threat-detection' -import { RealTimeSecurityAlerts } from '../real-time-security-alerts' -import { AdvancedAuditReporting } from '../advanced-audit-reporting' -import { ExternalMonitoringIntegration } from '../external-monitoring-integration' -import { SecurityTestFramework, TestRole, VulnerabilitySeverity, SecurityTestResult } from './security-test-framework' +import { PrismaClient } from '@prisma/client' + import { SecurityLogger } from '../../../lib/security-logger' +import { AdvancedAuditReporting } from '../advanced-audit-reporting' +import { AutomatedThreatDetection } from '../automated-threat-detection' +import { ExternalMonitoringIntegration } from '../external-monitoring-integration' +import { RealTimeSecurityAlerts } from '../real-time-security-alerts' + +import { SecurityTestFramework, TestRole, VulnerabilitySeverity, SecurityTestResult } from './security-test-framework' + export class ThreatDetectionIntegrationTests extends SecurityTestFramework { private threatDetection: AutomatedThreatDetection @@ -371,7 +374,7 @@ export class ThreatDetectionIntegrationTests extends SecurityTestFramework { resourceId: event.resourceId, timestamp: event.timestamp, metadata: event.metadata, - } + }, ) if (threat) { @@ -382,7 +385,7 @@ export class ThreatDetectionIntegrationTests extends SecurityTestFramework { // Должна быть обнаружена угроза data scraping const datascrapingDetected = detectedThreats.some(threat => - threat.modelId === 'data-scraping-detection' && threat.riskScore > 70 + threat.modelId === 'data-scraping-detection' && threat.riskScore > 70, ) return { @@ -451,7 +454,7 @@ export class ThreatDetectionIntegrationTests extends SecurityTestFramework { this.prisma, suspiciousActivity.userId, suspiciousActivity.action, - suspiciousActivity + suspiciousActivity, ) // Ждем немного для обработки events @@ -460,7 +463,7 @@ export class ThreatDetectionIntegrationTests extends SecurityTestFramework { const threatDetected = threat && threat.riskScore > 70 const alertTriggered = alertsReceived > 0 const alertMatchesThreat = receivedAlerts.some(alert => - alert.metadata.threatId === threat?.id + alert.metadata.threatId === threat?.id, ) return { diff --git a/src/graphql/security/__tests__/wholesale-security-tests.ts b/src/graphql/security/__tests__/wholesale-security-tests.ts index 6a57de5..cb5063b 100644 --- a/src/graphql/security/__tests__/wholesale-security-tests.ts +++ b/src/graphql/security/__tests__/wholesale-security-tests.ts @@ -8,9 +8,10 @@ import { PrismaClient } from '@prisma/client' import { GraphQLError } from 'graphql' -import { SupplyDataFilter } from '../supply-data-filter' -import { ParticipantIsolation } from '../participant-isolation' import { CommercialDataAudit } from '../commercial-data-audit' +import { ParticipantIsolation } from '../participant-isolation' +import { SupplyDataFilter } from '../supply-data-filter' + import { SecurityTestFramework, TestRole, VulnerabilitySeverity, SecurityTestResult } from './security-test-framework' export class WholesaleSecurityTests extends SecurityTestFramework { @@ -254,7 +255,7 @@ export class WholesaleSecurityTests extends SecurityTestFramework { // Ищем заказ, где есть продукты этого wholesale const orderWithOwnProducts = this.getTestData().supplyOrders.find(order => - order.items.some(item => item.product.organizationId === wholesaleUser.organizationId) + order.items.some(item => item.product.organizationId === wholesaleUser.organizationId), ) if (!orderWithOwnProducts) { @@ -271,7 +272,7 @@ export class WholesaleSecurityTests extends SecurityTestFramework { // WHOLESALE должен видеть свои цены на товары const canSeeOwnPrices = filteredResult.data.items?.some(item => item.product?.organizationId === wholesaleUser.organizationId && - item.price !== undefined + item.price !== undefined, ) return { @@ -283,7 +284,7 @@ export class WholesaleSecurityTests extends SecurityTestFramework { removedFields: filteredResult.removedFields, wholesaleOrg: wholesaleUser.organizationId, orderOwnProducts: orderWithOwnProducts.items.filter(item => - item.product.organizationId === wholesaleUser.organizationId + item.product.organizationId === wholesaleUser.organizationId, ), }, vulnerability: !(hasAccess && canSeeOwnPrices) ? { @@ -319,7 +320,7 @@ export class WholesaleSecurityTests extends SecurityTestFramework { // Ищем заказ БЕЗ товаров этого wholesale const orderWithoutOwnProducts = this.getTestData().supplyOrders.find(order => - !order.items.some(item => item.product.organizationId === wholesaleUser.organizationId) + !order.items.some(item => item.product.organizationId === wholesaleUser.organizationId), ) if (!orderWithoutOwnProducts) { @@ -399,7 +400,7 @@ export class WholesaleSecurityTests extends SecurityTestFramework { const mockContext = this.createMockContext(wholesaleUser) const orderWithRecipe = this.getTestData().supplyOrders.find(order => - order.items.some(item => item.recipe && Object.keys(item.recipe).length > 0) + order.items.some(item => item.recipe && Object.keys(item.recipe).length > 0), ) if (!orderWithRecipe) { @@ -453,7 +454,7 @@ export class WholesaleSecurityTests extends SecurityTestFramework { const mockContext = this.createMockContext(wholesaleUser) const orderWithFulfillmentPrice = this.getTestData().supplyOrders.find(order => - order.fulfillmentServicePrice && order.fulfillmentServicePrice > 0 + order.fulfillmentServicePrice && order.fulfillmentServicePrice > 0, ) if (!orderWithFulfillmentPrice) { @@ -506,7 +507,7 @@ export class WholesaleSecurityTests extends SecurityTestFramework { const mockContext = this.createMockContext(wholesaleUser) const orderWithLogisticsPrice = this.getTestData().supplyOrders.find(order => - order.logisticsPrice && order.logisticsPrice > 0 + order.logisticsPrice && order.logisticsPrice > 0, ) if (!orderWithLogisticsPrice) { @@ -628,7 +629,7 @@ export class WholesaleSecurityTests extends SecurityTestFramework { permission.includes('MANAGE_SELLERS') || permission.includes('DELETE_ORDERS') || permission.includes('VIEW_ALL_SELLERS') || - permission.includes('ADMIN_SELLER_FUNCTIONS') + permission.includes('ADMIN_SELLER_FUNCTIONS'), ) // Дополнительная проверка - WHOLESALE не должен видеть админ данные в заказах @@ -682,7 +683,7 @@ export class WholesaleSecurityTests extends SecurityTestFramework { // Тестируем заказ с товарами этого wholesale const orderWithOwnProducts = this.getTestData().supplyOrders.find(order => - order.items.some(item => item.product.organizationId === wholesaleUser.organizationId) + order.items.some(item => item.product.organizationId === wholesaleUser.organizationId), ) if (!orderWithOwnProducts) { @@ -695,22 +696,22 @@ export class WholesaleSecurityTests extends SecurityTestFramework { // Проверяем разрешения на изменение статуса const canChangeAllowedStatuses = allowedStatusChanges.every(status => - this.canWholesaleChangeStatus(wholesaleUser, status, orderWithOwnProducts) + this.canWholesaleChangeStatus(wholesaleUser, status, orderWithOwnProducts), ) const cannotChangeForbiddenStatuses = forbiddenStatusChanges.every(status => - !this.canWholesaleChangeStatus(wholesaleUser, status, orderWithOwnProducts) + !this.canWholesaleChangeStatus(wholesaleUser, status, orderWithOwnProducts), ) // Тестируем заказ БЕЗ товаров этого wholesale const orderWithoutOwnProducts = this.getTestData().supplyOrders.find(order => - !order.items.some(item => item.product.organizationId === wholesaleUser.organizationId) + !order.items.some(item => item.product.organizationId === wholesaleUser.organizationId), ) let cannotChangeUnrelatedOrders = true if (orderWithoutOwnProducts) { cannotChangeUnrelatedOrders = allowedStatusChanges.every(status => - !this.canWholesaleChangeStatus(wholesaleUser, status, orderWithoutOwnProducts) + !this.canWholesaleChangeStatus(wholesaleUser, status, orderWithoutOwnProducts), ) } @@ -762,7 +763,7 @@ export class WholesaleSecurityTests extends SecurityTestFramework { // Тестируем заказ с товарами этого wholesale const orderWithOwnProducts = this.getTestData().supplyOrders.find(order => - order.items.some(item => item.product.organizationId === wholesaleUser.organizationId) + order.items.some(item => item.product.organizationId === wholesaleUser.organizationId), ) if (!orderWithOwnProducts) { @@ -773,18 +774,18 @@ export class WholesaleSecurityTests extends SecurityTestFramework { const canApproveOwnProductOrders = this.canWholesaleApproveOrder( wholesaleUser, orderWithOwnProducts, - 'APPROVED' + 'APPROVED', ) const canRejectOwnProductOrders = this.canWholesaleApproveOrder( wholesaleUser, orderWithOwnProducts, - 'REJECTED' + 'REJECTED', ) // Тестируем заказ БЕЗ товаров этого wholesale const orderWithoutOwnProducts = this.getTestData().supplyOrders.find(order => - !order.items.some(item => item.product.organizationId === wholesaleUser.organizationId) + !order.items.some(item => item.product.organizationId === wholesaleUser.organizationId), ) let cannotApproveUnrelatedOrders = true @@ -792,7 +793,7 @@ export class WholesaleSecurityTests extends SecurityTestFramework { cannotApproveUnrelatedOrders = !this.canWholesaleApproveOrder( wholesaleUser, orderWithoutOwnProducts, - 'APPROVED' + 'APPROVED', ) } @@ -907,7 +908,7 @@ export class WholesaleSecurityTests extends SecurityTestFramework { 'SUPPLIER_CONFIRMED', 'SUPPLIER_PREPARING', 'SUPPLIER_SHIPPED', - 'SUPPLIER_DELIVERED_TO_FULFILLMENT' + 'SUPPLIER_DELIVERED_TO_FULFILLMENT', ] return allowedStatuses.includes(status) diff --git a/src/graphql/security/advanced-audit-reporting.ts b/src/graphql/security/advanced-audit-reporting.ts index ef67b1d..b9747f0 100644 --- a/src/graphql/security/advanced-audit-reporting.ts +++ b/src/graphql/security/advanced-audit-reporting.ts @@ -6,7 +6,9 @@ */ import { PrismaClient } from '@prisma/client' + import { SecurityLogger } from '../../lib/security-logger' + import { CommercialAccessType, ResourceType, SecurityAlert } from './types' /** diff --git a/src/graphql/security/automated-threat-detection.ts b/src/graphql/security/automated-threat-detection.ts index e17a24b..e62cd84 100644 --- a/src/graphql/security/automated-threat-detection.ts +++ b/src/graphql/security/automated-threat-detection.ts @@ -5,10 +5,12 @@ * для выявления подозрительной активности и потенциальных угроз безопасности */ -import { PrismaClient } from '@prisma/client' import { EventEmitter } from 'events' +import { PrismaClient } from '@prisma/client' + import { SecurityLogger } from '../../lib/security-logger' + import { RealTimeSecurityAlerts } from './real-time-security-alerts' import { CommercialAccessType, ResourceType, SecurityAlert } from './types' diff --git a/src/graphql/security/external-monitoring-integration.ts b/src/graphql/security/external-monitoring-integration.ts index 1277588..6ab2f9f 100644 --- a/src/graphql/security/external-monitoring-integration.ts +++ b/src/graphql/security/external-monitoring-integration.ts @@ -6,9 +6,11 @@ */ import { EventEmitter } from 'events' + import { PrismaClient } from '@prisma/client' import { SecurityLogger } from '../../lib/security-logger' + import { SecurityAlert } from './types' /** @@ -775,20 +777,20 @@ export class ExternalMonitoringIntegration extends EventEmitter { const lines: string[] = [] const timestamp = metrics.timestamp.getTime() - lines.push(`# HELP sfera_security_alerts_total Total number of security alerts`) - lines.push(`# TYPE sfera_security_alerts_total counter`) + lines.push('# HELP sfera_security_alerts_total Total number of security alerts') + lines.push('# TYPE sfera_security_alerts_total counter') lines.push(`sfera_security_alerts_total ${metrics.totalAlerts} ${timestamp}`) - lines.push(`# HELP sfera_security_active_threats Current number of active threats`) - lines.push(`# TYPE sfera_security_active_threats gauge`) + lines.push('# HELP sfera_security_active_threats Current number of active threats') + lines.push('# TYPE sfera_security_active_threats gauge') lines.push(`sfera_security_active_threats ${metrics.activeThreats} ${timestamp}`) - lines.push(`# HELP sfera_security_risk_score Current overall risk score`) - lines.push(`# TYPE sfera_security_risk_score gauge`) + lines.push('# HELP sfera_security_risk_score Current overall risk score') + lines.push('# TYPE sfera_security_risk_score gauge') lines.push(`sfera_security_risk_score ${metrics.riskScore} ${timestamp}`) - lines.push(`# HELP sfera_security_user_accesses_total Total number of user data accesses`) - lines.push(`# TYPE sfera_security_user_accesses_total counter`) + lines.push('# HELP sfera_security_user_accesses_total Total number of user data accesses') + lines.push('# TYPE sfera_security_user_accesses_total counter') lines.push(`sfera_security_user_accesses_total ${metrics.userActivity.totalAccesses} ${timestamp}`) return lines.join('\n') diff --git a/src/graphql/security/index.ts b/src/graphql/security/index.ts index a7b24da..247b730 100644 --- a/src/graphql/security/index.ts +++ b/src/graphql/security/index.ts @@ -99,7 +99,7 @@ export function createSecurityContext(context: any): SecurityContext { timestamp: new Date().toISOString(), ipAddress: context.req?.ip || context.req?.socket?.remoteAddress, userAgent: context.req?.headers?.['user-agent'], - } + }, } } diff --git a/src/graphql/security/middleware.ts b/src/graphql/security/middleware.ts index 3554dc6..97c98bb 100644 --- a/src/graphql/security/middleware.ts +++ b/src/graphql/security/middleware.ts @@ -5,18 +5,19 @@ * без необходимости переписывания всего кода */ -import { GraphQLError } from 'graphql' import { OrganizationType } from '@prisma/client' +import { GraphQLError } from 'graphql' import { FEATURE_FLAGS } from '../../config/features' import { SecurityLogger } from '../../lib/security-logger' -import { SupplyDataFilter } from './supply-data-filter' -import { ParticipantIsolation } from './participant-isolation' import { CommercialDataAudit } from './commercial-data-audit' +import { ParticipantIsolation } from './participant-isolation' +import { SupplyDataFilter } from './supply-data-filter' +import type { SecurityContext, ResourceType, CommercialAccessType } from './types' + import { createSecurityContext } from './index' -import type { SecurityContext, ResourceType, CommercialAccessType } from './types' /** * Конфигурация безопасности для резолвера diff --git a/src/graphql/security/security-dashboard-graphql.ts b/src/graphql/security/security-dashboard-graphql.ts index ae49df8..886b6cb 100644 --- a/src/graphql/security/security-dashboard-graphql.ts +++ b/src/graphql/security/security-dashboard-graphql.ts @@ -8,11 +8,12 @@ import { PrismaClient } from '@prisma/client' import { GraphQLError } from 'graphql' -import { AdvancedAuditReporting } from './advanced-audit-reporting' -import { RealTimeSecurityAlerts } from './real-time-security-alerts' -import { CommercialDataAudit } from './commercial-data-audit' import { SecurityLogger } from '../../lib/security-logger' +import { AdvancedAuditReporting } from './advanced-audit-reporting' +import { CommercialDataAudit } from './commercial-data-audit' +import { RealTimeSecurityAlerts } from './real-time-security-alerts' + interface SecurityDashboardContext { user: { id: string diff --git a/src/graphql/security/supply-data-filter.ts b/src/graphql/security/supply-data-filter.ts index 6cd6edb..3adbb18 100644 --- a/src/graphql/security/supply-data-filter.ts +++ b/src/graphql/security/supply-data-filter.ts @@ -230,7 +230,7 @@ export class SupplyDataFilter { productId: item.productId, productOrgId: item.product?.organizationId, hasProduct: !!item.product, - })) + })), ) const myItems = order.items.filter((item) => item.product.organizationId === organizationId)