This commit is contained in:
Professional 2025-05-26 18:05:58 +07:00
parent e8c839d493
commit 489f718fec
3 changed files with 61 additions and 41 deletions

View File

@ -29,8 +29,8 @@ const isBrowser = typeof window !== 'undefined' && typeof document !== 'undefine
console.log('Инициализация системы безопасности устройств...');
await deviceSecurityService.initialize();
// Подписываемся на события блокировки устройства
deviceSecurityService.onDeviceBlocked(handleDeviceBlocked);
// Исправлено: Используем правильный метод onDeviceBlock вместо onDeviceBlocked
deviceSecurityService.onDeviceBlock(handleDeviceBlocked);
console.log('Система безопасности устройств инициализирована');

View File

@ -18,6 +18,7 @@ class DeviceSecurityService {
this.suspiciousActivities = [];
this.lastFingerprintCheck = null;
this.checkInterval = null;
this.blockCallbacks = []; // Добавляем массив для хранения колбэков блокировки
// Настройки мониторинга
this.config = {
@ -277,6 +278,17 @@ class DeviceSecurityService {
}
}
/**
* Добавляет обработчик события блокировки устройства
* @param {Function} callback Функция обратного вызова
*/
onDeviceBlock(callback) {
if (typeof callback === 'function' && !this.blockCallbacks.includes(callback)) {
this.blockCallbacks.push(callback);
console.log('[DeviceSecurity] Добавлен обработчик события блокировки устройства');
}
}
/**
* Обработка блокировки устройства
*/
@ -289,6 +301,17 @@ class DeviceSecurityService {
// Очищаем локальные данные
this.clearLocalData();
// Вызываем все зарегистрированные обработчики
if (this.blockCallbacks && this.blockCallbacks.length > 0) {
this.blockCallbacks.forEach(callback => {
try {
callback(blockInfo);
} catch (e) {
console.error('[DeviceSecurity] Ошибка в обработчике блокировки устройства:', e);
}
});
}
// Показываем уведомление пользователю
this.showBlockedNotification(blockInfo);

View File

@ -175,54 +175,51 @@ class DeviceFingerprint {
return new Promise((resolve) => {
try {
// Если AudioContext недоступен, просто пропускаем этот шаг
if (!window.AudioContext && !window.webkitAudioContext) {
console.warn('[DeviceFingerprint] AudioContext не поддерживается');
this.components.set('audio', 'not-available');
resolve();
return;
}
const AudioContext = window.AudioContext || window.webkitAudioContext;
const context = new AudioContext();
const oscillator = context.createOscillator();
const analyser = context.createAnalyser();
const gainNode = context.createGain();
const scriptProcessor = context.createScriptProcessor(4096, 1, 1);
oscillator.type = 'triangle';
oscillator.frequency.value = 10000;
gainNode.gain.value = 0;
oscillator.connect(analyser);
analyser.connect(scriptProcessor);
scriptProcessor.connect(gainNode);
gainNode.connect(context.destination);
scriptProcessor.onaudioprocess = async (event) => {
const bins = new Float32Array(analyser.frequencyBinCount);
analyser.getFloatFrequencyData(bins);
const audioHash = await this.hashString(bins.slice(0, 50).join(','));
this.components.set('audio', audioHash);
oscillator.disconnect();
context.close();
resolve();
// Создаём аудио хэш на основе доступных properties AudioContext
// без использования ScriptProcessorNode
const createAudioFingerprintFallback = () => {
try {
const AudioContext = window.AudioContext || window.webkitAudioContext;
const context = new AudioContext();
const audioProps = {
sampleRate: context.sampleRate,
state: context.state,
baseLatency: context.baseLatency || 0,
outputLatency: context.outputLatency || 0
};
// Преобразуем эти свойства в хэш
const audioHash = this.simpleHash(JSON.stringify(audioProps));
this.components.set('audio', audioHash);
// Закрываем context
if (context.state !== 'closed') {
context.close();
}
resolve();
} catch (e) {
console.warn('[DeviceFingerprint] Ошибка в audio fingerprint fallback:', e);
this.components.set('audio', 'error');
resolve();
}
};
oscillator.start();
// Таймаут на случай проблем
setTimeout(() => {
try {
oscillator.disconnect();
context.close();
} catch (e) {}
resolve();
}, 1000);
// Используем безопасный fallback вместо устаревшего ScriptProcessor
// и AudioWorklet (который требует отдельного файла и https)
createAudioFingerprintFallback();
} catch (e) {
console.warn('[DeviceFingerprint] Не удалось создать audio fingerprint:', e);
this.components.set('audio', 'error');
resolve();
}
});