nakama/backend/middleware/auth.js

119 lines
3.7 KiB
JavaScript
Raw Normal View History

2025-11-03 20:35:01 +00:00
const crypto = require('crypto');
const User = require('../models/User');
// Проверка Telegram Init Data
function validateTelegramWebAppData(initData, botToken) {
const urlParams = new URLSearchParams(initData);
const hash = urlParams.get('hash');
urlParams.delete('hash');
const dataCheckString = Array.from(urlParams.entries())
.sort(([a], [b]) => a.localeCompare(b))
.map(([key, value]) => `${key}=${value}`)
.join('\n');
const secretKey = crypto
.createHmac('sha256', 'WebAppData')
.update(botToken)
.digest();
const calculatedHash = crypto
.createHmac('sha256', secretKey)
.update(dataCheckString)
.digest('hex');
return calculatedHash === hash;
}
// Middleware для проверки авторизации
const authenticate = async (req, res, next) => {
try {
const initData = req.headers['x-telegram-init-data'];
if (!initData) {
return res.status(401).json({ error: 'Не авторизован' });
}
// В dev режиме можно пропустить проверку
if (process.env.NODE_ENV === 'development') {
// Получаем user из initData
const urlParams = new URLSearchParams(initData);
const userParam = urlParams.get('user');
if (userParam) {
const telegramUser = JSON.parse(userParam);
req.telegramUser = telegramUser;
// Найти или создать пользователя
let user = await User.findOne({ telegramId: telegramUser.id.toString() });
if (!user) {
user = new User({
telegramId: telegramUser.id.toString(),
username: telegramUser.username || telegramUser.first_name,
firstName: telegramUser.first_name,
lastName: telegramUser.last_name,
photoUrl: telegramUser.photo_url
});
await user.save();
}
req.user = user;
return next();
}
}
// Проверка подписи Telegram
const isValid = validateTelegramWebAppData(initData, process.env.TELEGRAM_BOT_TOKEN);
if (!isValid) {
return res.status(401).json({ error: 'Неверные данные авторизации' });
}
const urlParams = new URLSearchParams(initData);
const userParam = urlParams.get('user');
const telegramUser = JSON.parse(userParam);
req.telegramUser = telegramUser;
// Найти или создать пользователя
let user = await User.findOne({ telegramId: telegramUser.id.toString() });
if (!user) {
user = new User({
telegramId: telegramUser.id.toString(),
username: telegramUser.username || telegramUser.first_name,
firstName: telegramUser.first_name,
lastName: telegramUser.last_name,
photoUrl: telegramUser.photo_url
});
await user.save();
}
req.user = user;
next();
} catch (error) {
console.error('Ошибка авторизации:', error);
res.status(401).json({ error: 'Ошибка авторизации' });
}
};
// Middleware для проверки роли модератора
const requireModerator = (req, res, next) => {
if (req.user.role !== 'moderator' && req.user.role !== 'admin') {
return res.status(403).json({ error: 'Требуются права модератора' });
}
next();
};
// Middleware для проверки роли админа
const requireAdmin = (req, res, next) => {
if (req.user.role !== 'admin') {
return res.status(403).json({ error: 'Требуются права администратора' });
}
next();
};
module.exports = {
authenticate,
requireModerator,
requireAdmin
};