Описание изменений
This commit is contained in:
160
backend/app.js
160
backend/app.js
@@ -7,67 +7,100 @@ const helmet = require('helmet');
|
||||
const path = require('path');
|
||||
const logger = require('./utils/logger');
|
||||
const authService = require('./services/auth-service');
|
||||
const { errorHandler, AppError, ErrorTypes } = require('./middleware/errorHandler');
|
||||
const aiAssistant = require('./services/ai-assistant');
|
||||
const crypto = require('crypto');
|
||||
|
||||
// Импорт маршрутов
|
||||
const authRoutes = require('./routes/auth');
|
||||
const accessRoutes = require('./routes/access');
|
||||
const usersRoutes = require('./routes/users');
|
||||
const contractsRoutes = require('./routes/contracts');
|
||||
const rolesRoutes = require('./routes/roles');
|
||||
const identitiesRoutes = require('./routes/identities');
|
||||
// const conversationsRoutes = require('./routes/conversations');
|
||||
const messagesRoutes = require('./routes/messages');
|
||||
const chatRoutes = require('./routes/chat');
|
||||
const healthRoutes = require('./routes/health');
|
||||
const debugRoutes = require('./routes/debug');
|
||||
const adminRoutes = require('./routes/admin');
|
||||
|
||||
const app = express();
|
||||
|
||||
// Настройка middleware для сессий
|
||||
// Настройка CORS
|
||||
app.use(cors({
|
||||
origin: 'http://localhost:5173',
|
||||
credentials: true,
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
||||
allowedHeaders: ['Content-Type', 'Authorization', 'Cookie']
|
||||
}));
|
||||
|
||||
// Настройка сессии
|
||||
app.use(session({
|
||||
store: new pgSession({
|
||||
pool,
|
||||
tableName: 'session',
|
||||
createTableIfMissing: true,
|
||||
}),
|
||||
secret: process.env.SESSION_SECRET || 'your-secret-key',
|
||||
secret: process.env.SESSION_SECRET || 'hb3atoken',
|
||||
name: 'sessionId',
|
||||
resave: false,
|
||||
saveUninitialized: true,
|
||||
cookie: {
|
||||
maxAge: 30 * 24 * 60 * 60 * 1000, // 30 дней
|
||||
maxAge: 30 * 24 * 60 * 60 * 1000,
|
||||
httpOnly: true,
|
||||
secure: false,
|
||||
sameSite: 'lax',
|
||||
},
|
||||
path: '/'
|
||||
}
|
||||
}));
|
||||
|
||||
// Добавим middleware для проверки сессии
|
||||
app.use(async (req, res, next) => {
|
||||
console.log('Request cookies:', req.headers.cookie);
|
||||
console.log('Session ID:', req.sessionID);
|
||||
|
||||
// Проверяем сессию в базе данных
|
||||
if (req.sessionID) {
|
||||
const result = await pool.query(
|
||||
'SELECT sess FROM session WHERE sid = $1',
|
||||
[req.sessionID]
|
||||
);
|
||||
console.log('Session from DB:', result.rows[0]?.sess);
|
||||
}
|
||||
|
||||
// Если сессия уже есть, используем её
|
||||
if (req.session.authenticated) {
|
||||
return next();
|
||||
}
|
||||
|
||||
// Проверяем заголовок авторизации
|
||||
const authHeader = req.headers.authorization;
|
||||
if (authHeader && authHeader.startsWith('Bearer ')) {
|
||||
const token = authHeader.split(' ')[1];
|
||||
try {
|
||||
// Находим пользователя по токену
|
||||
const { rows } = await pool.query(`
|
||||
SELECT u.id,
|
||||
(u.role = 'admin') as is_admin,
|
||||
u.address
|
||||
FROM users u
|
||||
WHERE u.id = $1
|
||||
`, [token]);
|
||||
|
||||
if (rows.length > 0) {
|
||||
const user = rows[0];
|
||||
req.session.userId = user.id;
|
||||
req.session.address = user.address;
|
||||
req.session.isAdmin = user.is_admin;
|
||||
req.session.authenticated = true;
|
||||
|
||||
await new Promise(resolve => req.session.save(resolve));
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error checking auth header:', error);
|
||||
}
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
|
||||
// Настройка парсеров
|
||||
app.use(express.json());
|
||||
app.use(express.urlencoded({ extended: true }));
|
||||
|
||||
// Настройка CORS
|
||||
app.use(cors({
|
||||
origin: function(origin, callback) {
|
||||
// Разрешаем запросы с localhost и 127.0.0.1
|
||||
const allowedOrigins = [
|
||||
'http://localhost:5173',
|
||||
'http://127.0.0.1:5173',
|
||||
'http://localhost:3000',
|
||||
'http://127.0.0.1:3000',
|
||||
process.env.CORS_ORIGIN
|
||||
].filter(Boolean);
|
||||
|
||||
if (!origin || allowedOrigins.includes(origin)) {
|
||||
callback(null, true);
|
||||
} else {
|
||||
callback(new Error('Not allowed by CORS'));
|
||||
}
|
||||
},
|
||||
credentials: true,
|
||||
methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'],
|
||||
allowedHeaders: ['Content-Type', 'Authorization']
|
||||
}));
|
||||
|
||||
// Настройка безопасности
|
||||
app.use(helmet({
|
||||
contentSecurityPolicy: false // Отключаем CSP для разработки
|
||||
@@ -79,34 +112,51 @@ app.use((req, res, next) => {
|
||||
next();
|
||||
});
|
||||
|
||||
// Добавляем middleware для установки заголовков CORS
|
||||
app.use((req, res, next) => {
|
||||
res.header('Access-Control-Allow-Origin', req.headers.origin || '*');
|
||||
res.header('Access-Control-Allow-Credentials', 'true');
|
||||
res.header('Access-Control-Allow-Methods', 'GET,HEAD,PUT,PATCH,POST,DELETE');
|
||||
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept, Authorization');
|
||||
next();
|
||||
});
|
||||
|
||||
// Маршруты API
|
||||
app.use('/api/auth', authRoutes);
|
||||
app.use('/api/access', accessRoutes);
|
||||
app.use('/api/users', usersRoutes);
|
||||
app.use('/api/contracts', contractsRoutes);
|
||||
app.use('/api/roles', rolesRoutes);
|
||||
app.use('/api/identities', identitiesRoutes);
|
||||
// app.use('/api/conversations', conversationsRoutes);
|
||||
app.use('/api/messages', messagesRoutes);
|
||||
app.use('/api/chat', chatRoutes);
|
||||
app.use('/api/health', healthRoutes);
|
||||
|
||||
// Маршруты для отладки (только в режиме разработки)
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
app.use('/api/debug', debugRoutes);
|
||||
}
|
||||
app.use('/api/admin', adminRoutes);
|
||||
|
||||
const nonceStore = new Map(); // или любая другая реализация хранилища nonce
|
||||
|
||||
console.log('SESSION_SECRET:', process.env.SESSION_SECRET);
|
||||
|
||||
// Добавляем обработчик ошибок последним
|
||||
app.use(errorHandler);
|
||||
|
||||
// Эндпоинт для проверки состояния
|
||||
app.get('/api/health', async (req, res) => {
|
||||
try {
|
||||
// Проверяем подключение к БД
|
||||
await pool.query('SELECT NOW()');
|
||||
|
||||
// Проверяем AI сервис
|
||||
const aiStatus = await aiAssistant.checkHealth();
|
||||
|
||||
res.json({
|
||||
status: 'ok',
|
||||
timestamp: new Date().toISOString(),
|
||||
database: 'connected',
|
||||
ai: aiStatus
|
||||
});
|
||||
} catch (error) {
|
||||
logger.error('Health check failed:', error);
|
||||
res.status(500).json({
|
||||
status: 'error',
|
||||
error: error.message
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
// Очистка старых сессий
|
||||
setInterval(async () => {
|
||||
try {
|
||||
await pool.query('DELETE FROM session WHERE expire < NOW()');
|
||||
} catch (error) {
|
||||
console.error('Error cleaning old sessions:', error);
|
||||
}
|
||||
}, 15 * 60 * 1000); // Каждые 15 минут
|
||||
|
||||
module.exports = { app, nonceStore };
|
||||
|
||||
Reference in New Issue
Block a user