const bcrypt = require('bcryptjs'); const fetch = require('node-fetch'); class AuthService { constructor() { this.db = null; } setDatabase(database) { this.db = database; this.initUsers(); } initUsers() { if (!this.db) return; const users = [ { login: process.env.USER_1_LOGIN, password: process.env.USER_1_PASSWORD, name: process.env.USER_1_NAME, email: process.env.USER_1_EMAIL, role: process.env.USER_1_ROLE || 'admin' } ]; for (const u of users) { if (u.login && u.password) { this.createUserIfNotExists(u); } } } async createUserIfNotExists(userData) { const row = this.db.prepare('SELECT id FROM users WHERE login = ?').get(userData.login); if (!row) { const hashedPassword = await bcrypt.hash(userData.password, 10); this.db.prepare( "INSERT INTO users (login, password, name, email, role, auth_type, created_at) VALUES (?, ?, ?, ?, ?, ?, datetime('now'))" ).run(userData.login, hashedPassword, userData.name, userData.email || null, userData.role, userData.auth_type || 'local'); console.log('Создан пользователь: ' + userData.name); } } authenticate(login, password) { const user = this.authenticateLocal(login, password); if (user) return user; return null; } authenticateLocal(login, password) { const user = this.db.prepare("SELECT * FROM users WHERE login = ? AND auth_type = 'local'").get(login); if (!user) return null; const isValid = bcrypt.compareSync(password, user.password); if (isValid) { this.db.prepare("UPDATE users SET last_login = datetime('now') WHERE id = ?").run(user.id); const { password, ...userWithoutPassword } = user; return userWithoutPassword; } return null; } async authenticateWithLDAP(login, password) { if (!this.db) return null; if (!process.env.LDAP_AUTH_URL) return null; try { const response = await fetch(process.env.LDAP_AUTH_URL, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ username: login, password }) }); if (!response.ok) return null; const data = await response.json(); if (!data.success) return null; return this.processLDAPUser(data); } catch (error) { console.error('Ошибка LDAP аутентификации:', error.message); return null; } } processLDAPUser(ldapData) { if (!this.db) return null; const { username, full_name, groups } = ldapData; const userGroups = groups || []; const allowedGroups = process.env.ALLOWED_GROUPS ? process.env.ALLOWED_GROUPS.split(',').map(g => g.trim()) : []; let role = 'teacher'; if (userGroups.some(group => allowedGroups.includes(group))) { role = 'admin'; } const existingUser = this.db.prepare("SELECT * FROM users WHERE login = ? AND auth_type = 'ldap'").get(username); if (existingUser) { this.db.prepare( "UPDATE users SET name = ?, email = ?, role = ?, groups = ?, last_login = datetime('now') WHERE id = ?" ).run(full_name || username, username + '@school25.ru', role, JSON.stringify(userGroups), existingUser.id); const { password, ...userWithoutPassword } = existingUser; return { ...userWithoutPassword, name: full_name || username, email: username + '@school25.ru', role, groups: JSON.stringify(userGroups) }; } else { this.db.prepare( "INSERT INTO users (login, name, email, role, auth_type, groups, created_at, last_login) VALUES (?, ?, ?, ?, 'ldap', ?, datetime('now'), datetime('now'))" ).run(username, full_name || username, username + '@school25.ru', role, JSON.stringify(userGroups)); const newUser = this.db.prepare("SELECT * FROM users WHERE login = ? AND auth_type = 'ldap'").get(username); if (newUser) { const { password, ...userWithoutPassword } = newUser; console.log('Создан LDAP пользователь: ' + (full_name || username)); return userWithoutPassword; } } return null; } getUserById(id) { const user = this.db.prepare('SELECT id, login, name, email, role, auth_type, created_at, last_login FROM users WHERE id = ?').get(id); return user || null; } } const authService = new AuthService(); module.exports = authService;