Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using StreamVideo.Core;
using StreamVideo.Core.Configs;
using StreamVideo.Core.Exceptions;
using StreamVideo.Core.StatefulModels;
using StreamVideo.Core.StatefulModels.Tracks;
using StreamVideo.Libs;
using StreamVideo.Libs.Auth;
using StreamVideo.Libs.Serialization;
using StreamVideo.Libs.Utils;
using UnityEngine;
#if STREAM_DEBUG_ENABLED
Expand Down Expand Up @@ -244,24 +243,6 @@ protected void OnApplicationPause(bool pauseStatus)
}
#endif

/// <summary>
/// API success response template when using Stream's Demo Credentials
/// </summary>
private class DemoCredentialsApiResponse
{
public string UserId;
public string Token;
public string APIKey;
}

/// <summary>
/// API error response template when using Stream's Demo Credentials
/// </summary>
private class DemoCredentialsApiError
{
public string Error;
}

#pragma warning disable CS0414 //Disable warning that _info is unused. It's purpose is to display info box in the Unity Inspector only

[SerializeField]
Expand All @@ -281,6 +262,10 @@ private string _info
[SerializeField]
private string _userToken = "";

[Header("Demo Credentials")]
[SerializeField]
private StreamEnvironment _environment = StreamEnvironment.Demo;

[Header("Background Music in a call")]
[SerializeField]
private AudioClip _musicClip = null;
Expand Down Expand Up @@ -312,46 +297,16 @@ private async Task ConnectToStreamAsync(AuthCredentials credentials)

if (credentialsEmpty)
{
// If custom credentials are not defined - use Stream's Demo Credentials
Debug.Log("Authorization credentials were not provided. Using Stream's Demo Credentials.");

var demoCredentials = await GetStreamDemoTokenAsync();
credentials = new AuthCredentials(demoCredentials.APIKey, demoCredentials.UserId,
demoCredentials.Token);
var factory = new StreamDependenciesFactory();
var provider = factory.CreateDemoCredentialsProvider();
credentials = await provider.GetDemoCredentialsAsync("DemoUser", _environment);
}

await Client.ConnectUserAsync(credentials);
}

/// <summary>
/// This method will fetch Stream's demo credentials. These credentials are not usable in a real production due to limited rates.
/// Customer accounts do have a FREE tier so please register at https://getstream.io/ to get your own app ID and credentials.
/// </summary>
private static async Task<DemoCredentialsApiResponse> GetStreamDemoTokenAsync()
{
var serializer = new NewtonsoftJsonSerializer();
var httpClient = new HttpClient();
var uriBuilder = new UriBuilder
{
Host = "pronto.getstream.io",
Path = "/api/auth/create-token",
Query = $"user_id=DemoUser",
Scheme = "https",
};

var uri = uriBuilder.Uri;
var response = await httpClient.GetAsync(uri);
var result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
var apiError = serializer.Deserialize<DemoCredentialsApiError>(result);
throw new Exception(
$"Failed to get demo credentials. Error status code: `{response.StatusCode}`, Error message: `{apiError.Error}`");
}

return serializer.Deserialize<DemoCredentialsApiResponse>(result);
}

private void OnCallStarted(IStreamCall call)
{
_activeCall = call;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
using System;
using System.Threading;
using System.Threading.Tasks;
using StreamVideo.Libs.Http;
using StreamVideo.Libs.Serialization;

namespace StreamVideo.Libs.Auth
{
/// <summary>
/// Fetches demo/test credentials (API key + user token) from the Pronto endpoint.
/// DO NOT USE IN PRODUCTION. These credentials are rate-limited and meant only for internal testing and demo apps.
/// Customer accounts have a FREE tier for testing — please register at https://getstream.io/ to get your own app ID and credentials.
/// </summary>
public class StreamDemoCredentialsProvider
{
public StreamDemoCredentialsProvider(IHttpClient httpClient, ISerializer serializer)
{
_httpClient = httpClient ?? throw new ArgumentNullException(nameof(httpClient));
_serializer = serializer ?? throw new ArgumentNullException(nameof(serializer));
}

/// <summary>
/// Fetch demo credentials from <c>https://pronto.getstream.io/api/auth/create-token</c>.
/// The returned <see cref="AuthCredentials"/> contains the API key, user ID, and signed token.
/// DO NOT USE IN PRODUCTION. Customer accounts have a FREE tier for testing —
/// please register at https://getstream.io/ to get your own app ID and credentials.
/// </summary>
public async Task<AuthCredentials> GetDemoCredentialsAsync(
string userId,
StreamEnvironment environment = StreamEnvironment.Demo,
CancellationToken cancellationToken = default)
{
if (string.IsNullOrEmpty(userId))
{
throw new ArgumentException("User ID must not be null or empty.", nameof(userId));
}

var uri = new UriBuilder
{
Scheme = "https",
Host = Host,
Path = Path,
Query = $"user_id={Uri.EscapeDataString(userId)}&environment={ToQueryValue(environment)}",
}.Uri;

var response = await _httpClient.GetAsync(uri, cancellationToken);
if (!response.IsSuccessStatusCode)
{
string errorMessage = null;
try
{
var error = _serializer.Deserialize<ErrorResponse>(response.Result);
errorMessage = error?.Error;
}
catch
{
// ignored — use raw response below
}

throw new Exception(
$"Failed to get demo credentials. Status code: {response.StatusCode}, " +
$"Error: {errorMessage ?? response.Result}");
}

var result = _serializer.Deserialize<CredentialsResponse>(response.Result);
return new AuthCredentials(result.ApiKey, result.UserId, result.Token);
}

private const string Host = "pronto.getstream.io";
private const string Path = "/api/auth/create-token";

private static string ToQueryValue(StreamEnvironment environment)
{
switch (environment)
{
case StreamEnvironment.Demo: return "demo";
case StreamEnvironment.Pronto: return "pronto";
default: throw new ArgumentOutOfRangeException(nameof(environment), environment,
$"Unsupported environment: {environment}");
}
}

private class CredentialsResponse
{
public string UserId;
public string ApiKey;
public string Token;
}

private class ErrorResponse
{
public string Error;
}

private readonly IHttpClient _httpClient;
private readonly ISerializer _serializer;
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

11 changes: 11 additions & 0 deletions Packages/StreamVideo/Runtime/Libs/Auth/StreamEnvironment.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace StreamVideo.Libs.Auth
{
/// <summary>
/// Stream backend environment used when fetching demo credentials from Pronto.
/// </summary>
public enum StreamEnvironment
{
Demo,
Pronto,
}
}
11 changes: 11 additions & 0 deletions Packages/StreamVideo/Runtime/Libs/Auth/StreamEnvironment.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using StreamVideo.Libs.AppInfo;
using StreamVideo.Libs.AppInfo;
using StreamVideo.Libs.Auth;
using StreamVideo.Libs.VideoClientInstanceRunner;
using StreamVideo.Libs.Http;
Expand Down Expand Up @@ -48,6 +48,9 @@ public virtual IHttpClient CreateHttpClient()

public virtual ITokenProvider CreateTokenProvider(TokenProvider.TokenUriHandler urlFactory) => new TokenProvider(CreateHttpClient(), urlFactory);

public virtual StreamDemoCredentialsProvider CreateDemoCredentialsProvider()
=> new StreamDemoCredentialsProvider(CreateHttpClient(), CreateSerializer());

public virtual IStreamVideoClientRunner CreateClientRunner()
{
var go = new GameObject
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using StreamVideo.Core;
using StreamVideo.Core.Configs;
using StreamVideo.Core.Exceptions;
using StreamVideo.Core.StatefulModels;
using StreamVideo.Core.StatefulModels.Tracks;
using StreamVideo.Libs;
using StreamVideo.Libs.Auth;
using StreamVideo.Libs.Serialization;
using StreamVideo.Libs.Utils;
using UnityEngine;
#if STREAM_DEBUG_ENABLED
Expand Down Expand Up @@ -244,24 +243,6 @@ protected void OnApplicationPause(bool pauseStatus)
}
#endif

/// <summary>
/// API success response template when using Stream's Demo Credentials
/// </summary>
private class DemoCredentialsApiResponse
{
public string UserId;
public string Token;
public string APIKey;
}

/// <summary>
/// API error response template when using Stream's Demo Credentials
/// </summary>
private class DemoCredentialsApiError
{
public string Error;
}

#pragma warning disable CS0414 //Disable warning that _info is unused. It's purpose is to display info box in the Unity Inspector only

[SerializeField]
Expand All @@ -281,6 +262,10 @@ private string _info
[SerializeField]
private string _userToken = "";

[Header("Demo Credentials")]
[SerializeField]
private StreamEnvironment _environment = StreamEnvironment.Demo;

[Header("Background Music in a call")]
[SerializeField]
private AudioClip _musicClip = null;
Expand Down Expand Up @@ -312,46 +297,16 @@ private async Task ConnectToStreamAsync(AuthCredentials credentials)

if (credentialsEmpty)
{
// If custom credentials are not defined - use Stream's Demo Credentials
Debug.Log("Authorization credentials were not provided. Using Stream's Demo Credentials.");

var demoCredentials = await GetStreamDemoTokenAsync();
credentials = new AuthCredentials(demoCredentials.APIKey, demoCredentials.UserId,
demoCredentials.Token);
var factory = new StreamDependenciesFactory();
var provider = factory.CreateDemoCredentialsProvider();
credentials = await provider.GetDemoCredentialsAsync("DemoUser", _environment);
}

await Client.ConnectUserAsync(credentials);
}

/// <summary>
/// This method will fetch Stream's demo credentials. These credentials are not usable in a real production due to limited rates.
/// Customer accounts do have a FREE tier so please register at https://getstream.io/ to get your own app ID and credentials.
/// </summary>
private static async Task<DemoCredentialsApiResponse> GetStreamDemoTokenAsync()
{
var serializer = new NewtonsoftJsonSerializer();
var httpClient = new HttpClient();
var uriBuilder = new UriBuilder
{
Host = "pronto.getstream.io",
Path = "/api/auth/create-token",
Query = $"user_id=DemoUser",
Scheme = "https",
};

var uri = uriBuilder.Uri;
var response = await httpClient.GetAsync(uri);
var result = await response.Content.ReadAsStringAsync();
if (!response.IsSuccessStatusCode)
{
var apiError = serializer.Deserialize<DemoCredentialsApiError>(result);
throw new Exception(
$"Failed to get demo credentials. Error status code: `{response.StatusCode}`, Error message: `{apiError.Error}`");
}

return serializer.Deserialize<DemoCredentialsApiResponse>(result);
}

private void OnCallStarted(IStreamCall call)
{
_activeCall = call;
Expand Down
Loading
Loading