Внешний TURN

This commit is contained in:
Халимов Рустам
2026-03-11 16:18:56 +03:00
parent 18f39ecea8
commit 926482861f
4 changed files with 48 additions and 1 deletions
+9 -1
View File
@@ -30,7 +30,15 @@ export const config = {
minPasswordLength: 8,
/** Maximum registrations allowed from the same IP (permanent, DB-level) */
maxRegistrationsPerIp: Number(process.env.MAX_REGISTRATIONS_PER_IP) || 2,
/** TURN server URL (e.g. turn:openrelay.metered.ca:80) */
turnUrl: process.env.TURN_URL || '',
/** FOR DYNAMIC AUTH: Shared secret (coturn / metered.ca) */
turnSecret: process.env.TURN_SECRET || '',
/** FOR STATIC AUTH: Username */
turnUsername: process.env.TURN_USERNAME || '',
/** FOR STATIC AUTH: Password */
turnPassword: process.env.TURN_PASSWORD || '',
/** STUN server URLs */
stunUrls: (process.env.STUN_URLS || 'stun:stun.yandex.ru:3478,stun:stun.sipnet.net:3478,stun:stun.l.google.com:19302,stun:stun.voip.aebc.com:3478,stun:stun.stunprotocol.org:3478')
stunUrls: (process.env.STUN_URLS || 'stun:stun.yandex.ru:3478,stun:stun.mail.ru:3478,stun:stun.sipnet.net:3478,stun:stun.l.google.com:19302,stun:stun.voip.aebc.com:3478')
.split(',').map(s => s.trim()).filter(Boolean),
};
+29
View File
@@ -124,6 +124,35 @@ app.get('/api/ice-servers', authenticateToken, (_req: AuthRequest, res) => {
iceServers.push({ urls: config.stunUrls });
}
// TURN сервер (динамическая или статическая аутентификация)
if (config.turnUrl) {
const urls = config.turnUrl.split(',').map(s => s.trim());
if (config.turnSecret) {
// Динамический пароль (HMAC-SHA1)
const ttl = 48 * 3600;
const timestamp = Math.floor(Date.now() / 1000) + ttl;
const username = `${timestamp}:vortex`;
const credential = crypto
.createHmac('sha1', config.turnSecret)
.update(username)
.digest('base64');
iceServers.push({
urls: urls,
username,
credential,
});
} else if (config.turnUsername && config.turnPassword) {
// Статичный логин/пароль
iceServers.push({
urls: urls,
username: config.turnUsername,
credential: config.turnPassword,
});
}
}
res.json({ iceServers });
});
+7
View File
@@ -319,6 +319,13 @@ export default function CallModal({ isOpen, onClose, targetUser, callType: initi
setCallState('calling');
try {
// Security context check (critical for KeenDNS)
if (!window.isSecureContext) {
alert('Критическая ошибка: Совершение аудио/видео звонков требует безопасного соединения (HTTPS).\n\nЗайдите в настройки KeenDNS и убедитесь, что включено HTTPS (SSL), а в браузере используйте https:// вместо http://');
setCallState('ended');
return;
}
// Get media (video with camera enumeration fallback)
console.log('[startCall] Getting media, wantVideo:', callType === 'video');
const { stream, hasVideo } = await getMediaWithCameraFallback(callType === 'video');
+3
View File
@@ -24,6 +24,9 @@ services:
JWT_SECRET: ${JWT_SECRET:-your-secure-random-secret-key-here}
CORS_ORIGINS: ${CORS_ORIGINS:-http://localhost,http://localhost:80,http://localhost:9090,http://localhost:5173,http://${DOMAIN:-mess.khomegeneric.keenetic.pro},https://${DOMAIN:-mess.khomegeneric.keenetic.pro}}
ENCRYPTION_KEY: ${ENCRYPTION_KEY:-0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef}
TURN_URL: ${TURN_URL:-}
TURN_USERNAME: ${TURN_USERNAME:-}
TURN_PASSWORD: ${TURN_PASSWORD:-}
depends_on:
- db
ports: