Skip to content

Develop --> Main#16

Merged
martian56 merged 4 commits intomainfrom
develop
Nov 9, 2025
Merged

Develop --> Main#16
martian56 merged 4 commits intomainfrom
develop

Conversation

@martian56
Copy link
Owner

This pull request updates the WebRTC configuration to dynamically fetch TURN server credentials from the Metered API, improving security and flexibility. It removes hardcoded credentials from the codebase and updates environment configuration and workflow files to support the new approach.

WebRTC Configuration & TURN Server Credentials

  • Replaced hardcoded Metered TURN server credentials in RTC_CONFIG with logic to fetch credentials dynamically from the Metered API using the VITE_METERED_API_KEY environment variable in config.ts. This also introduces a fallback to Google's public STUN server if fetching fails.
  • Refactored the useWebRTC hook to use the new fetchIceServers function for initializing peer connections, ensuring credentials are fetched once and cached for reuse. All peer connection creation logic now awaits the dynamic fetching of ICE servers. [1] [2] [3] [4] [5]

Environment & Deployment Configuration

  • Added VITE_METERED_API_KEY to the .env.example file with instructions for obtaining the key, and clarified usage for local and production API URLs.
  • Updated the GitHub Actions deployment workflow to inject the Metered API key from repository secrets for production deployments.

@martian56 martian56 added this to the MVP version milestone Nov 9, 2025
@martian56 martian56 requested a review from Copilot November 9, 2025 13:24
@martian56 martian56 self-assigned this Nov 9, 2025
@martian56 martian56 added bug Something isn't working documentation Improvements or additions to documentation enhancement New feature or request CI/CD Merge labels Nov 9, 2025
@martian56 martian56 merged commit d30cef0 into main Nov 9, 2025
8 checks passed
@github-project-automation github-project-automation bot moved this from Backlog to Done in LinkUp Project Nov 9, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR updates the WebRTC configuration to dynamically fetch TURN server credentials from the Metered API instead of using hardcoded credentials. The main changes include:

  • Dynamic fetching of ICE servers with caching
  • Environment variable configuration for the Metered API key
  • Async handling in peer connection creation

Reviewed Changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 5 comments.

File Description
frontend/src/config.ts Added fetchIceServers function to dynamically fetch TURN credentials from Metered API with fallback to STUN servers
frontend/src/hooks/useWebRTC.ts Updated createPeerConnection to be async, fetch ICE servers on demand with caching, and updated all call sites
frontend/.env.example Added environment variable documentation for VITE_METERED_API_KEY
.github/workflows/deploy_front.yml Added secret injection for the Metered API key in deployment workflow

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +7 to +12
export const METERED_API_URL = `https://linkup-ufazien.metered.live/api/v1/turn/credentials?apiKey=${METERED_API_KEY}`;

// Function to fetch TURN server credentials
export const fetchIceServers = async (): Promise<RTCIceServer[]> => {
try {
const response = await fetch(METERED_API_URL);
Copy link

Copilot AI Nov 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The API key is exposed in the URL query string. While this appears to be client-side code where the key must be public, consider if there are API rate limits or abuse concerns. The Metered API documentation should be checked to ensure this is the intended usage pattern. If the API supports it, consider using request headers for authentication instead.

Suggested change
export const METERED_API_URL = `https://linkup-ufazien.metered.live/api/v1/turn/credentials?apiKey=${METERED_API_KEY}`;
// Function to fetch TURN server credentials
export const fetchIceServers = async (): Promise<RTCIceServer[]> => {
try {
const response = await fetch(METERED_API_URL);
export const METERED_API_URL = 'https://linkup-ufazien.metered.live/api/v1/turn/credentials';
// Function to fetch TURN server credentials
export const fetchIceServers = async (): Promise<RTCIceServer[]> => {
try {
const response = await fetch(METERED_API_URL, {
headers: {
'Authorization': `Bearer ${METERED_API_KEY}`
}
});

Copilot uses AI. Check for mistakes.
Comment on lines +45 to +49
if (!iceServersRef.current) {
console.log('Fetching TURN server credentials...');
iceServersRef.current = await fetchIceServers();
console.log('ICE servers fetched:', iceServersRef.current);
}
Copy link

Copilot AI Nov 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Race condition: If createPeerConnection is called simultaneously for multiple peers before the first fetch completes, multiple concurrent fetchIceServers() calls will be made. Consider implementing a promise-based lock pattern or storing the promise itself to ensure only one fetch occurs. Example: if (!iceServersPromise) { iceServersPromise = fetchIceServers(); } iceServersRef.current = await iceServersPromise;

Copilot uses AI. Check for mistakes.
Comment on lines 30 to 36
export const RTC_CONFIG: RTCConfiguration = {
iceServers: [
{
urls: 'stun:stun.relay.metered.ca:80'
},
{
urls: 'turn:global.relay.metered.ca:80',
username: '81df41330ffff0c3d75e77ed',
credential: 'yn1jtZhMFeVgGmYo'
},
{
urls: 'turn:global.relay.metered.ca:80?transport=tcp',
username: '81df41330ffff0c3d75e77ed',
credential: 'yn1jtZhMFeVgGmYo'
},
{
urls: 'turn:global.relay.metered.ca:443',
username: '81df41330ffff0c3d75e77ed',
credential: 'yn1jtZhMFeVgGmYo'
},
{
urls: 'turns:global.relay.metered.ca:443?transport=tcp',
username: '81df41330ffff0c3d75e77ed',
credential: 'yn1jtZhMFeVgGmYo'
urls: 'stun:stun.l.google.com:19302'
}
]
};
Copy link

Copilot AI Nov 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The RTC_CONFIG export is no longer used after switching to dynamic ICE server fetching. Consider removing this unused export to avoid confusion and maintain cleaner code.

Copilot uses AI. Check for mistakes.
try {
const response = await fetch(METERED_API_URL);
if (!response.ok) {
throw new Error('Failed to fetch TURN credentials');
Copy link

Copilot AI Nov 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The error message could be more descriptive by including the HTTP status code or response details. Consider: throw new Error(\Failed to fetch TURN credentials: ${response.status} ${response.statusText}`);`

Suggested change
throw new Error('Failed to fetch TURN credentials');
throw new Error(`Failed to fetch TURN credentials: ${response.status} ${response.statusText}`);

Copilot uses AI. Check for mistakes.
env:
VITE_API_URL: https://videoo-call.onrender.com
VITE_WS_URL: wss://videoo-call.onrender.com
VITE_METERED_API_KEY: ${{ secrets.VITE_METERED_API_KEY }}
Copy link

Copilot AI Nov 9, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Extra whitespace between colon and value. Should be single space for consistency with other environment variables.

Suggested change
VITE_METERED_API_KEY: ${{ secrets.VITE_METERED_API_KEY }}
VITE_METERED_API_KEY: ${{ secrets.VITE_METERED_API_KEY }}

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working bugfix CI/CD documentation Improvements or additions to documentation enhancement New feature or request Merge Release

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

2 participants