bc/server/auth/authService.js

153 lines
8.8 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// /server/auth/authService.js
const bcrypt = require('bcryptjs'); // Для хеширования паролей
const jwt = require('jsonwebtoken'); // <<< ДОБАВЛЕНО
const db = require('../core/db'); // Путь к вашему модулю для работы с базой данных
const SALT_ROUNDS = 10; // Количество раундов для генерации соли bcrypt
/**
* Регистрирует нового пользователя и генерирует JWT.
* @param {string} username - Имя пользователя.
* @param {string} password - Пароль пользователя.
* @returns {Promise<object>} Объект с результатом: { success: boolean, message: string, token?: string, userId?: number, username?: string }
*/
async function registerUser(username, password) {
console.log(`[AuthService DEBUG] registerUser called with username: "${username}"`);
if (!username || !password) {
console.warn('[AuthService DEBUG] Validation failed: Username or password empty.');
return { success: false, message: 'Имя пользователя и пароль не могут быть пустыми.' };
}
if (password.length < 6) {
console.warn(`[AuthService DEBUG] Validation failed for "${username}": Password too short.`);
return { success: false, message: 'Пароль должен содержать не менее 6 символов.' };
}
try {
// Этап A: Проверка существующего пользователя
console.log(`[AuthService DEBUG] Stage A: Checking if user "${username}" exists...`);
// Предполагаем, что db.query возвращает массив, где первый элемент - это массив строк (результатов)
const [existingUsers] = await db.query('SELECT id FROM users WHERE username = ?', [username]);
console.log(`[AuthService DEBUG] Stage A: existingUsers query result length: ${existingUsers.length}`);
if (existingUsers.length > 0) {
console.warn(`[AuthService DEBUG] Registration declined for "${username}": Username already taken.`);
return { success: false, message: 'Это имя пользователя уже занято.' };
}
console.log(`[AuthService DEBUG] Stage A: Username "${username}" is available.`);
// Этап B: Хеширование пароля
console.log(`[AuthService DEBUG] Stage B: Hashing password for user "${username}"...`);
const hashedPassword = await bcrypt.hash(password, SALT_ROUNDS);
console.log(`[AuthService DEBUG] Stage B: Password for "${username}" hashed successfully.`);
// Этап C: Сохранение пользователя в БД
console.log(`[AuthService DEBUG] Stage C: Attempting to insert user "${username}" into DB...`);
// Предполагаем, что db.query для INSERT возвращает объект результата с insertId
const [result] = await db.query(
'INSERT INTO users (username, password_hash) VALUES (?, ?)',
[username, hashedPassword]
);
console.log(`[AuthService DEBUG] Stage C: DB insert result for "${username}":`, result);
if (result && result.insertId) {
const userId = result.insertId;
// Генерируем JWT токен
const tokenPayload = { userId: userId, username: username };
const token = jwt.sign(
tokenPayload,
process.env.JWT_SECRET, // Используем секрет из .env
{ expiresIn: process.env.JWT_EXPIRES_IN || '1h' } // Используем срок из .env или по умолчанию 1 час
);
console.log(`[AuthService] Пользователь "${username}" успешно зарегистрирован с ID: ${userId}. Токен выдан.`);
return {
success: true,
message: 'Регистрация прошла успешно! Вы вошли в систему.',
token: token, // <<< ВОЗВРАЩАЕМ ТОКЕН
userId: userId,
username: username // Возвращаем и имя пользователя
};
} else {
console.error(`[AuthService] Ошибка БД при регистрации пользователя "${username}": Запись не была вставлена или insertId отсутствует. Result:`, result);
return { success: false, message: 'Ошибка сервера при регистрации (данные не сохранены). Попробуйте позже.' };
}
} catch (error) {
console.error(`[AuthService] КРИТИЧЕСКАЯ ОШИБКА (catch block) при регистрации пользователя "${username}":`, error);
if (error.sqlMessage) {
console.error(`[AuthService] MySQL Error Message: ${error.sqlMessage}`);
console.error(`[AuthService] MySQL Error Code: ${error.code}`);
console.error(`[AuthService] MySQL Errno: ${error.errno}`);
}
return { success: false, message: 'Внутренняя ошибка сервера при регистрации.' };
}
}
/**
* Выполняет вход пользователя и генерирует JWT.
* @param {string} username - Имя пользователя.
* @param {string} password - Пароль пользователя.
* @returns {Promise<object>} Объект с результатом: { success: boolean, message: string, token?: string, userId?: number, username?: string }
*/
async function loginUser(username, password) {
console.log(`[AuthService DEBUG] loginUser called with username: "${username}"`);
if (!username || !password) {
console.warn('[AuthService DEBUG] Login validation failed: Username or password empty.');
return { success: false, message: 'Имя пользователя и пароль не могут быть пустыми.' };
}
try {
console.log(`[AuthService DEBUG] Searching for user "${username}" in DB...`);
const [users] = await db.query('SELECT id, username, password_hash FROM users WHERE username = ?', [username]);
console.log(`[AuthService DEBUG] DB query result for user "${username}" (length): ${users.length}`);
if (users.length === 0) {
console.warn(`[AuthService DEBUG] Login failed: User "${username}" not found.`);
return { success: false, message: 'Неверное имя пользователя или пароль.' };
}
const user = users[0];
console.log(`[AuthService DEBUG] User "${username}" found. ID: ${user.id}. Comparing password...`);
const passwordMatch = await bcrypt.compare(password, user.password_hash);
console.log(`[AuthService DEBUG] Password comparison result for "${username}": ${passwordMatch}`);
if (passwordMatch) {
// Генерируем JWT токен
const tokenPayload = { userId: user.id, username: user.username };
const token = jwt.sign(
tokenPayload,
process.env.JWT_SECRET, // Используем секрет из .env
{ expiresIn: process.env.JWT_EXPIRES_IN || '1h' } // Используем срок из .env или по умолчанию 1 час
);
console.log(`[AuthService] Пользователь "${user.username}" (ID: ${user.id}) успешно вошел в систему. Токен выдан.`);
return {
success: true,
message: 'Вход выполнен успешно!',
token: token, // <<< ВОЗВРАЩАЕМ ТОКЕН
userId: user.id,
username: user.username // Возвращаем имя пользователя
};
} else {
console.warn(`[AuthService DEBUG] Login failed for user "${user.username}": Incorrect password.`);
return { success: false, message: 'Неверное имя пользователя или пароль.' };
}
} catch (error) {
console.error(`[AuthService] КРИТИЧЕСКАЯ ОШИБКА (catch block) при входе пользователя "${username}":`, error);
if (error.sqlMessage) {
console.error(`[AuthService] MySQL Error Message: ${error.sqlMessage}`);
console.error(`[AuthService] MySQL Error Code: ${error.code}`);
console.error(`[AuthService] MySQL Errno: ${error.errno}`);
}
return { success: false, message: 'Внутренняя ошибка сервера при входе.' };
}
}
module.exports = {
registerUser,
loginUser
};