adding cloudflare turn service option

This commit is contained in:
balzack 2024-06-02 09:28:54 -07:00
parent cd801a7679
commit 5663e2761d
6 changed files with 91 additions and 44 deletions

View File

@ -160,6 +160,7 @@ const Strings = [
enableVideo: 'Enable Video Queue', enableVideo: 'Enable Video Queue',
enableBinary: 'Enable Binary Files', enableBinary: 'Enable Binary Files',
enableCalls: 'Enable WebRTC Calls', enableCalls: 'Enable WebRTC Calls',
iceService: 'Cloudflare Service',
relayUrl: 'Relay URL', relayUrl: 'Relay URL',
relayUsername: 'Relay Username', relayUsername: 'Relay Username',
relayPassword: 'Relay Password', relayPassword: 'Relay Password',
@ -370,6 +371,7 @@ const Strings = [
enableVideo: 'Activer les Fichiers Vidéo', enableVideo: 'Activer les Fichiers Vidéo',
enableBinary: 'Activer les Fichiers Binaires', enableBinary: 'Activer les Fichiers Binaires',
enableCalls: 'Activer les Appels', enableCalls: 'Activer les Appels',
iceService: 'Service Cloudflare',
relayUrl: 'URL de Relais', relayUrl: 'URL de Relais',
relayUsername: 'Nom d\'Utilisateur du Relais', relayUsername: 'Nom d\'Utilisateur du Relais',
relayPassword: 'Mot de Passe du Relais', relayPassword: 'Mot de Passe du Relais',
@ -580,6 +582,7 @@ const Strings = [
enableVideo: 'Permitir Archivos de Vídeo', enableVideo: 'Permitir Archivos de Vídeo',
enableBinary: 'Permitir Archivos Binarios', enableBinary: 'Permitir Archivos Binarios',
enableCalls: 'Permitier Llamadas', enableCalls: 'Permitier Llamadas',
iceService: 'Servicio Cloudflare',
relayUrl: 'URL para Llamadas', relayUrl: 'URL para Llamadas',
relayUsername: 'Nombre de Usuario para Llamadas', relayUsername: 'Nombre de Usuario para Llamadas',
relayPassword: 'Contraseña para Llamadas', relayPassword: 'Contraseña para Llamadas',
@ -791,6 +794,7 @@ const Strings = [
enableVideo: 'Videodateien aktivieren', enableVideo: 'Videodateien aktivieren',
enableBinary: 'Binärdateien aktivieren', enableBinary: 'Binärdateien aktivieren',
enableCalls: 'Anrufe Ermöglichen', enableCalls: 'Anrufe Ermöglichen',
iceService: 'Cloudflare-Dienst',
relayUrl: 'URL für Anrufe', relayUrl: 'URL für Anrufe',
relayUsername: 'Benutzername für Anrufe', relayUsername: 'Benutzername für Anrufe',
relayPassword: 'Passwort für Anrufe', relayPassword: 'Passwort für Anrufe',
@ -990,6 +994,7 @@ const Strings = [
enableVideo: 'Habilitar Fila de Vídeo', enableVideo: 'Habilitar Fila de Vídeo',
enableBinary: 'Habilitar Fila Binários', enableBinary: 'Habilitar Fila Binários',
enableCalls: 'Habilitar Chamadas WebRTC', enableCalls: 'Habilitar Chamadas WebRTC',
iceService: 'Serviço Cloudflare',
relayUrl: 'URL do Relay', relayUrl: 'URL do Relay',
relayUsername: 'Nome de Usuário do Relay', relayUsername: 'Nome de Usuário do Relay',
relayPassword: 'Senha do Relay', relayPassword: 'Senha do Relay',
@ -1186,6 +1191,7 @@ const Strings = [
enableVideo: 'Включить очередь видео', enableVideo: 'Включить очередь видео',
enableBinary: 'Включить двоичные файлы', enableBinary: 'Включить двоичные файлы',
enableCalls: 'Включить звонки WebRTC', enableCalls: 'Включить звонки WebRTC',
iceService: 'Сервис Cloudflare',
relayUrl: 'URL релея', relayUrl: 'URL релея',
relayUsername: 'Имя пользователя релея', relayUsername: 'Имя пользователя релея',
relayPassword: 'Пароль релея', relayPassword: 'Пароль релея',

View File

@ -213,8 +213,9 @@ export function useAppContext() {
card.actions.setRevision(cardRev); card.actions.setRevision(cardRev);
} }
else if (activity.ring) { else if (activity.ring) {
const { cardId, callId, calleeToken, iceUrl, iceUsername, icePassword } = activity.ring; const { cardId, callId, calleeToken, ice, iceUrl, iceUsername, icePassword } = activity.ring;
ring.actions.ring(cardId, callId, calleeToken, iceUrl, iceUsername, icePassword); const config = ice ? ice : [{ urls: iceUrl, username: iceUsername, credential: icePassword }];
ring.actions.ring(cardId, callId, calleeToken, config);
} }
else { else {
const { profile: profileRev, account: accountRev, channel: channelRev, card: cardRev } = activity; const { profile: profileRev, account: accountRev, channel: channelRev, card: cardRev } = activity;

View File

@ -331,9 +331,9 @@ export function useRingContext() {
clearSession: () => { clearSession: () => {
access.current = null; access.current = null;
}, },
ring: (cardId, callId, calleeToken, iceUrl, iceUsername, icePassword) => { ring: (cardId, callId, calleeToken, ice) => {
const key = `${cardId}:${callId}` const key = `${cardId}:${callId}`
const call = ringing.current.get(key) || { cardId, calleeToken, callId, iceUrl, iceUsername, icePassword } const call = ringing.current.get(key) || { cardId, calleeToken, callId, ice }
call.expires = Date.now() + EXPIRE; call.expires = Date.now() + EXPIRE;
ringing.current.set(key, call); ringing.current.set(key, call);
updateState({ ringing: ringing.current }); updateState({ ringing: ringing.current });
@ -365,7 +365,7 @@ export function useRingContext() {
} }
} }
}, },
accept: async (cardId, callId, contactNode, contactToken, calleeToken, iceUrl, iceUsername, icePassword) => { accept: async (cardId, callId, contactNode, contactToken, calleeToken, ice) => {
if (calling.current) { if (calling.current) {
throw new Error("active session"); throw new Error("active session");
} }
@ -378,7 +378,6 @@ export function useRingContext() {
updateState({ ringing: ringing.current, callStatus: "connecting", cardId }); updateState({ ringing: ringing.current, callStatus: "connecting", cardId });
calling.current = { callId, contactNode, contactToken, host: false }; calling.current = { callId, contactNode, contactToken, host: false };
const ice = [{ urls: iceUrl, username: iceUsername, credential: icePassword }];
await connect('impolite', contactNode, calleeToken, () => {}, () => {}, ice); await connect('impolite', contactNode, calleeToken, () => {}, () => {}, ice);
} }
}, },
@ -422,9 +421,9 @@ export function useRingContext() {
throw err; throw err;
} }
const { id, keepAlive, callerToken, calleeToken, iceUrl, iceUsername, icePassword } = call; const { id, keepAlive, callerToken, calleeToken, ice, iceUrl, iceUsername, icePassword } = call;
try { try {
await addContactRing(contactNode, contactToken, { index, callId: id, calleeToken, iceUrl, iceUsername, icePassword }); await addContactRing(contactNode, contactToken, { index, callId: id, calleeToken, ice, iceUrl, iceUsername, icePassword });
} }
catch (err) { catch (err) {
console.log(err); console.log(err);
@ -446,7 +445,7 @@ export function useRingContext() {
} }
} }
else { else {
await addContactRing(contactNode, contactToken, { index, callId: id, calleeToken, iceUrl, iceUsername, icePassword }); await addContactRing(contactNode, contactToken, { index, callId: id, calleeToken, ice, iceUrl, iceUsername, icePassword });
index += 1; index += 1;
} }
} }
@ -457,8 +456,8 @@ export function useRingContext() {
updateState({ callStatus: "ringing" }); updateState({ callStatus: "ringing" });
calling.current = { callId: id, host: true }; calling.current = { callId: id, host: true };
const ice = [{ urls: iceUrl, username: iceUsername, credential: icePassword }]; const iceLegacy = [{ urls: iceUrl, username: iceUsername, credential: icePassword }];
await connect('polite', server, callerToken, () => clearInterval(ringInterval), () => clearInterval(aliveInterval), ice); await connect('polite', server, callerToken, () => clearInterval(ringInterval), () => clearInterval(aliveInterval), ice ? ice : iceLegacy);
}, },
enableVideo: async () => { enableVideo: async () => {
if (!videoTrack.current) { if (!videoTrack.current) {

View File

@ -283,33 +283,70 @@ export function Dashboard(props) {
onValueChange={actions.setEnableIce} trackColor={styles.track}/> onValueChange={actions.setEnableIce} trackColor={styles.track}/>
</TouchableOpacity> </TouchableOpacity>
<InputField style={styles.field} { state.enableIce && (
label={state.strings.relayUrl} <>
value={state.iceUrl} <TouchableOpacity style={styles.ice} activeOpacity={1}
autoCapitalize={'none'} onPress={() => actions.setEnableIce(!state.iceService)}>
spellCheck={false} <Text style={styles.modalLabel}>{ state.strings.iceService }</Text>
disabled={!state.enableIce} <Switch style={styles.switch} value={state.iceService}
onChangeText={actions.setIceUrl} onValueChange={actions.setIceService} trackColor={styles.track}/>
/> </TouchableOpacity>
<InputField style={styles.field} { !state.iceService && (
label={state.strings.relayUsername} <>
value={state.iceUsername} <InputField style={styles.field}
autoCapitalize={'none'} label={state.strings.relayUrl}
spellCheck={false} value={state.iceUrl}
disabled={!state.enableIce} autoCapitalize={'none'}
onChangeText={actions.setIceUsername} spellCheck={false}
/> disabled={!state.enableIce}
onChangeText={actions.setIceUrl}
/>
<InputField style={styles.field}
label={state.strings.relayUsername}
value={state.iceUsername}
autoCapitalize={'none'}
spellCheck={false}
disabled={!state.enableIce}
onChangeText={actions.setIceUsername}
/>
<InputField style={styles.field}
label={state.strings.relayPassword}
value={state.icePassword}
autoCapitalize={'none'}
spellCheck={false}
disabled={!state.enableIce}
onChangeText={actions.setIcePassword}
/>
</>
)}
{ state.iceService && (
<>
<InputField style={styles.field}
label={'TURN_KEY_ID'}
value={state.iceUsername}
autoCapitalize={'none'}
spellCheck={false}
disabled={!state.enableIce}
onChangeText={actions.setIceUsername}
/>
<InputField style={styles.field}
label={'TURN_KEY_API_TOKEN'}
value={state.icePassword}
autoCapitalize={'none'}
spellCheck={false}
disabled={!state.enableIce}
onChangeText={actions.setIcePassword}
/>
</>
)}
</>
)}
<InputField style={styles.field}
label={state.strings.relayPassword}
value={state.icePassword}
autoCapitalize={'none'}
spellCheck={false}
disabled={!state.enableIce}
onChangeText={actions.setIcePassword}
/>
<View style={styles.pad} /> <View style={styles.pad} />
</ScrollView> </ScrollView>

View File

@ -41,6 +41,7 @@ export function useDashboard(server, token, mfa) {
enableBinary: true, enableBinary: true,
createToken: null, createToken: null,
enableIce: false, enableIce: false,
iceService: false,
iceUrl: null, iceUrl: null,
iceUsername: null, iceUsername: null,
icePassword: null, icePassword: null,
@ -78,9 +79,9 @@ export function useDashboard(server, token, mfa) {
const config = await getNodeConfig(server, token); const config = await getNodeConfig(server, token);
const nodeAccounts = await getNodeAccounts(server, token); const nodeAccounts = await getNodeAccounts(server, token);
const accounts = nodeAccounts.map(setAccountItem); const accounts = nodeAccounts.map(setAccountItem);
const { keyType, accountStorage, domain, enableImage, enableAudio, enableVideo, enableBinary, transformSupported, allowUnsealed, pushSupported, enableIce, iceUrl, iceUsername, icePassword } = config || {}; const { keyType, accountStorage, domain, enableImage, enableAudio, enableVideo, enableBinary, transformSupported, allowUnsealed, pushSupported, enableIce, iceService, iceUrl, iceUsername, icePassword } = config || {};
const storage = Math.ceil(accountStorage / 1073741824); const storage = Math.ceil(accountStorage / 1073741824);
updateState({ keyType, storage: storage.toString(), domain, enableImage, enableAudio, enableVideo, enableBinary, transformSupported, allowUnsealed, pushSupported, enableIce, iceUrl, iceUsername, icePassword, accounts, mfaEnabled }); updateState({ keyType, storage: storage.toString(), domain, enableImage, enableAudio, enableVideo, enableBinary, transformSupported, allowUnsealed, pushSupported, enableIce, iceService, iceUrl, iceUsername, icePassword, accounts, mfaEnabled });
} }
const refreshAccounts = async () => { const refreshAccounts = async () => {
@ -150,6 +151,9 @@ export function useDashboard(server, token, mfa) {
setEnableIce: (enableIce) => { setEnableIce: (enableIce) => {
updateState({ enableIce }); updateState({ enableIce });
}, },
setIceService: (iceService) => {
updateState({ iceService });
},
setIceUrl: (iceUrl) => { setIceUrl: (iceUrl) => {
updateState({ iceUrl }); updateState({ iceUrl });
}, },
@ -160,9 +164,9 @@ export function useDashboard(server, token, mfa) {
updateState({ icePassword }); updateState({ icePassword });
}, },
saveConfig: async () => { saveConfig: async () => {
const { storage, domain, keyType, enableImage, pushSupported, allowUnsealed, transformSupported, enableAudio, enableVideo, enableBinary, enableIce, iceUrl, iceUsername, icePassword } = state; const { storage, domain, keyType, enableImage, pushSupported, allowUnsealed, transformSupported, enableAudio, enableVideo, enableBinary, enableIce, iceService, iceUrl, iceUsername, icePassword } = state;
const accountStorage = Number(storage) * 1073741824; const accountStorage = Number(storage) * 1073741824;
const config = { accountStorage, domain, keyType, enableImage, pushSupported, allowUnsealed, transformSupported, enableAudio, enableVideo, enableBinary, enableIce, iceUrl, iceUsername, icePassword }; const config = { accountStorage, domain, keyType, enableImage, pushSupported, allowUnsealed, transformSupported, enableAudio, enableVideo, enableBinary, enableIce, iceService, iceUrl, iceUsername, icePassword };
await setNodeConfig(server, token, config); await setNodeConfig(server, token, config);
}, },
enableUser: async (accountId, enabled) => { enableUser: async (accountId, enabled) => {

View File

@ -49,7 +49,7 @@ export function useSession() {
const expired = Date.now(); const expired = Date.now();
ring.state.ringing.forEach(call => { ring.state.ringing.forEach(call => {
if (call.expires > expired && !call.status) { if (call.expires > expired && !call.status) {
const { callId, cardId, calleeToken, iceUrl, iceUsername, icePassword } = call; const { callId, cardId, calleeToken, ice } = call;
const contact = card.state.cards.get(cardId); const contact = card.state.cards.get(cardId);
if (contact) { if (contact) {
const { imageSet, name, handle, node, guid } = contact.card?.profile || {}; const { imageSet, name, handle, node, guid } = contact.card?.profile || {};
@ -57,7 +57,7 @@ export function useSession() {
const contactToken = `${guid}.${token}`; const contactToken = `${guid}.${token}`;
const server = node ? node : profile.state.server; const server = node ? node : profile.state.server;
const img = imageSet ? card.actions.getCardImageUrl(cardId) : null; const img = imageSet ? card.actions.getCardImageUrl(cardId) : null;
ringing.push({ cardId, img, name, handle, contactNode: server, callId, contactToken, calleeToken, iceUrl, iceUsername, icePassword }); ringing.push({ cardId, img, name, handle, contactNode: server, callId, contactToken, calleeToken, ice });
} }
} }
}); });
@ -124,8 +124,8 @@ export function useSession() {
await ring.actions.decline(cardId, contactNode, contactToken, callId); await ring.actions.decline(cardId, contactNode, contactToken, callId);
}, },
accept: async (call) => { accept: async (call) => {
const { cardId, callId, contactNode, contactToken, calleeToken, iceUrl, iceUsername, icePassword } = call; const { cardId, callId, contactNode, contactToken, calleeToken, ice } = call;
await ring.actions.accept(cardId, callId, contactNode, contactToken, calleeToken, iceUrl, iceUsername, icePassword); await ring.actions.accept(cardId, callId, contactNode, contactToken, calleeToken, ice);
}, },
end: async () => { end: async () => {
await ring.actions.end(); await ring.actions.end();