138 lines
4.7 KiB
TypeScript
138 lines
4.7 KiB
TypeScript
import { Injectable, Logger } from '@nestjs/common';
|
|
import { JwtService } from '@nestjs/jwt';
|
|
import { InjectRepository } from '@nestjs/typeorm';
|
|
import { Repository } from 'typeorm';
|
|
import * as bcrypt from 'bcrypt';
|
|
import { Setting } from '../settings/entities/setting.entity';
|
|
import { ConfigService } from '@nestjs/config';
|
|
|
|
@Injectable()
|
|
export class AuthService {
|
|
private readonly logger = new Logger(AuthService.name);
|
|
|
|
constructor(
|
|
@InjectRepository(Setting)
|
|
private settingsRepo: Repository<Setting>,
|
|
private jwtService: JwtService,
|
|
private configService: ConfigService,
|
|
) {}
|
|
|
|
async validateUser(
|
|
login: string,
|
|
pass: string,
|
|
): Promise<{ login: string } | null> {
|
|
this.logger.debug(`Попытка входа с логином: ${login}`);
|
|
|
|
const dbLogin = await this.settingsRepo.findOne({
|
|
where: { key: 'admin_login' },
|
|
});
|
|
const dbPass = await this.settingsRepo.findOne({
|
|
where: { key: 'admin_password' },
|
|
});
|
|
|
|
// Проверяем наличие учётных данных (без деталей для безопасности)
|
|
if (!dbLogin || !dbPass) {
|
|
this.logger.error('Учётные данные не найдены в базе данных');
|
|
return null;
|
|
}
|
|
|
|
this.logger.debug(`Пользователь найден, проверяем хеш пароля...`);
|
|
|
|
const isMatch = await bcrypt.compare(pass, dbPass.value);
|
|
|
|
if (isMatch) {
|
|
this.logger.debug('Пароль верный!');
|
|
return { login: dbLogin.value };
|
|
} else {
|
|
this.logger.warn('Пароль неверный.');
|
|
return null;
|
|
}
|
|
}
|
|
|
|
login(user: { login: string }) {
|
|
const payload = { username: user.login };
|
|
this.logger.debug(`Генерация access token для пользователя: ${user.login}`);
|
|
return {
|
|
access_token: this.jwtService.sign(payload),
|
|
};
|
|
}
|
|
|
|
async changePassword(newPass: string) {
|
|
const hash = await bcrypt.hash(newPass, 10);
|
|
let setting = await this.settingsRepo.findOne({
|
|
where: { key: 'admin_password' },
|
|
});
|
|
if (!setting) {
|
|
setting = this.settingsRepo.create({ key: 'admin_password' });
|
|
}
|
|
setting.value = hash;
|
|
await this.settingsRepo.save(setting);
|
|
this.logger.debug('Пароль администратора изменен.');
|
|
}
|
|
|
|
async updateAdminProfile(login: string, password?: string) {
|
|
let loginSetting = await this.settingsRepo.findOne({
|
|
where: { key: 'admin_login' },
|
|
});
|
|
if (!loginSetting)
|
|
loginSetting = this.settingsRepo.create({ key: 'admin_login' });
|
|
|
|
loginSetting.value = login;
|
|
await this.settingsRepo.save(loginSetting);
|
|
|
|
if (password && password.trim().length > 0) {
|
|
const hash = await bcrypt.hash(password, 10);
|
|
let passSetting = await this.settingsRepo.findOne({
|
|
where: { key: 'admin_password' },
|
|
});
|
|
if (!passSetting)
|
|
passSetting = this.settingsRepo.create({ key: 'admin_password' });
|
|
|
|
passSetting.value = hash;
|
|
await this.settingsRepo.save(passSetting);
|
|
}
|
|
|
|
this.logger.debug(`Профиль администратора обновлен. Новый логин: ${login}`);
|
|
}
|
|
|
|
async seedAdmin() {
|
|
const login = await this.settingsRepo.findOne({
|
|
where: { key: 'admin_login' },
|
|
});
|
|
|
|
if (!login) {
|
|
this.logger.debug('Инициализация администратора...');
|
|
const envLogin = this.configService.get<string>('ADMIN_LOGIN');
|
|
const envPass = this.configService.get<string>('ADMIN_PASSWORD');
|
|
|
|
// Проверяем, что переменные окружения установлены
|
|
if (!envLogin || !envPass) {
|
|
this.logger.error(
|
|
'Критическая ошибка: ADMIN_LOGIN и ADMIN_PASSWORD должны быть установлены в переменных окружения',
|
|
);
|
|
this.logger.error(
|
|
'Проверьте .env файл или docker-compose.yml на наличие этих переменных',
|
|
);
|
|
throw new Error('ADMIN_LOGIN и ADMIN_PASSWORD должны быть установлены');
|
|
}
|
|
|
|
const loginSetting = this.settingsRepo.create({
|
|
key: 'admin_login',
|
|
value: envLogin,
|
|
});
|
|
await this.settingsRepo.save(loginSetting);
|
|
|
|
const hash = await bcrypt.hash(envPass, 10);
|
|
const passSetting = this.settingsRepo.create({
|
|
key: 'admin_password',
|
|
value: hash,
|
|
});
|
|
await this.settingsRepo.save(passSetting);
|
|
|
|
this.logger.debug('Администратор успешно создан.');
|
|
} else {
|
|
this.logger.debug('Администратор уже существует в базе.');
|
|
}
|
|
}
|
|
}
|