Files
SchoolVue/auth.js
2026-07-07 10:43:31 +05:00

131 lines
4.8 KiB
JavaScript

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;