diff --git a/sample/Assets/Scripts/Other/LaunchBrowserScript.cs b/sample/Assets/Scripts/Other/LaunchBrowserScript.cs
index 970c58c1..975bd8a6 100644
--- a/sample/Assets/Scripts/Other/LaunchBrowserScript.cs
+++ b/sample/Assets/Scripts/Other/LaunchBrowserScript.cs
@@ -9,13 +9,13 @@ public class LaunchBrowserScript : MonoBehaviour
{
[SerializeField] private WebBrowserUIFull webBrowser;
[SerializeField] private Button openDevToolsButton;
-
+
private WebBrowserClient? webBrowserClient;
public void Start()
{
webBrowser.browserClient.OnLoadFinish += OnLoadFinish;
-
+
void OnLoadFinish(string url)
{
webBrowser.browserClient.OnLoadFinish -= OnLoadFinish;
diff --git a/sample/Assets/Scripts/Passport/SelectAuthMethodScript.cs b/sample/Assets/Scripts/Passport/SelectAuthMethodScript.cs
index d8517f66..9eec6809 100644
--- a/sample/Assets/Scripts/Passport/SelectAuthMethodScript.cs
+++ b/sample/Assets/Scripts/Passport/SelectAuthMethodScript.cs
@@ -90,6 +90,9 @@ private async void InitialisePassport(string? redirectUri = null, string? logout
// Set the log level for the SDK
Passport.LogLevel = LogLevel.Info;
+ // Don't redact token values from logs
+ Passport.RedactTokensInLogs = false;
+
// Initialise Passport
string environment = Immutable.Passport.Model.Environment.SANDBOX;
string clientId = "mp6rxfMDwwZDogcdgNrAaHnG0qMlXuMK";
diff --git a/src/Packages/Passport/Editor/PassportPostprocess.cs b/src/Packages/Passport/Editor/PassportPostprocess.cs
index 44df2365..cdea39f7 100644
--- a/src/Packages/Passport/Editor/PassportPostprocess.cs
+++ b/src/Packages/Passport/Editor/PassportPostprocess.cs
@@ -184,6 +184,6 @@ private void CopyFilesTo(string destinationPath)
}
}
}
-}
-
+}
+
#endif
\ No newline at end of file
diff --git a/src/Packages/Passport/Runtime/Scripts/Private/Core/Logging/PassportLogger.cs b/src/Packages/Passport/Runtime/Scripts/Private/Core/Logging/PassportLogger.cs
index 905a8dce..30e0e8f1 100644
--- a/src/Packages/Passport/Runtime/Scripts/Private/Core/Logging/PassportLogger.cs
+++ b/src/Packages/Passport/Runtime/Scripts/Private/Core/Logging/PassportLogger.cs
@@ -1,4 +1,4 @@
-using UnityEngine;
+using System;
namespace Immutable.Passport.Core.Logging
{
@@ -8,13 +8,24 @@ public static class PassportLogger
public static LogLevel CurrentLogLevel { get; set; } = LogLevel.Info;
- public static void Log(LogLevel level, string message)
+ ///
+ /// A function that defines how sensitive data should be redacted.
+ /// If null, no redaction is applied.
+ ///
+ public static Func? RedactionHandler { get; set; }
+
+ private static void Log(LogLevel level, string message)
{
if (level < CurrentLogLevel)
{
return; // Don't log messages below the current log level
}
+ if (RedactionHandler != null)
+ {
+ message = RedactionHandler(message);
+ }
+
switch (level)
{
case LogLevel.Debug:
@@ -30,7 +41,7 @@ public static void Log(LogLevel level, string message)
UnityEngine.Debug.LogError($"{TAG} {message}");
break;
default:
- break;
+ throw new ArgumentOutOfRangeException(nameof(level), level, null);
}
}
diff --git a/src/Packages/Passport/Runtime/Scripts/Private/PassportFunction.cs b/src/Packages/Passport/Runtime/Scripts/Private/PassportFunction.cs
index cf05ce50..76c5c967 100644
--- a/src/Packages/Passport/Runtime/Scripts/Private/PassportFunction.cs
+++ b/src/Packages/Passport/Runtime/Scripts/Private/PassportFunction.cs
@@ -6,7 +6,6 @@ public static class PassportFunction
public const string INIT_DEVICE_FLOW = "initDeviceFlow";
public const string RELOGIN = "relogin";
public const string RECONNECT = "reconnect";
- public const string CONNECT = "connect";
public const string LOGIN_PKCE = "loginPKCE";
public const string CONNECT_PKCE = "connectPKCE";
public const string GET_PKCE_AUTH_URL = "getPKCEAuthUrl";
diff --git a/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs b/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs
index c1d01def..7f937b51 100644
--- a/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs
+++ b/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs
@@ -1,10 +1,12 @@
using System.Collections.Generic;
using System;
+using System.Text.RegularExpressions;
#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
#if !IMMUTABLE_CUSTOM_BROWSER
using VoltstroStudios.UnityWebBrowser;
using VoltstroStudios.UnityWebBrowser.Core;
using VoltstroStudios.UnityWebBrowser.Shared;
+using VoltstroStudios.UnityWebBrowser.Logging;
#endif
#elif (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL
using Immutable.Browser.Gree;
@@ -48,13 +50,19 @@ public class Passport
public event OnAuthEventDelegate OnAuthEvent;
///
- /// The log level for the SDK.
+ /// Gets or sets the log level for the SDK.
///
///
- /// The log level determines which messages are recorded based on their severity. The default value is .
+ /// The log level determines which messages are recorded based on their severity.
+ ///
+ /// The default value is .
+ ///
///
/// See for valid log levels and their meanings.
///
+ ///
+ /// Passport.LogLevel = LogLevel.Debug;
+ ///
///
public static LogLevel LogLevel
{
@@ -72,6 +80,35 @@ public static LogLevel LogLevel
private static LogLevel _logLevel = LogLevel.Info;
+ ///
+ /// Determines whether sensitive token values should be redacted from SDK logs.
+ ///
+ ///
+ /// When set to true, access tokens and ID tokens will be replaced with [REDACTED]
in log messages to enhance security.
+ /// This setting is useful for preventing sensitive data from appearing in logs, especially when debugging or sharing logs with others.
+ ///
+ /// The default value is false, meaning tokens will be logged in full at appropriate log levels.
+ ///
+ ///
+ /// Passport.RedactTokensInLogs = true;
+ ///
+ ///
+ public static bool RedactTokensInLogs
+ {
+ get => _redactTokensInLogs;
+ set
+ {
+ _redactTokensInLogs = value;
+ PassportLogger.RedactionHandler = value ? RedactTokenValues : null;
+
+#if !IMMUTABLE_CUSTOM_BROWSER && (UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN))
+ SetWindowsRedactionHandler();
+#endif
+ }
+ }
+
+ private static bool _redactTokensInLogs;
+
private Passport()
{
// Handle clean-up tasks when the application is quitting
@@ -191,7 +228,7 @@ private async UniTask Initialise(
" 'windowsWebBrowserClient' must not be null.");
#else
webBrowserClient = gameObject.AddComponent();
- await ((UwbWebView)webBrowserClient).Init(engineStartupTimeoutMs);
+ await ((UwbWebView)webBrowserClient).Init(engineStartupTimeoutMs, _redactTokensInLogs, RedactTokenValues);
readySignalReceived = true;
#endif
}
@@ -558,8 +595,43 @@ private static void SetDefaultWindowsBrowserLogLevel()
};
}
}
+
+ private static void SetWindowsRedactionHandler()
+ {
+ if (Instance?.webBrowserClient is WebBrowserClient browserClient)
+ {
+ browserClient.Logger = new DefaultUnityWebBrowserLogger(redactionHandler: _redactTokensInLogs ? RedactTokenValues : null);
+ }
+ }
#endif
+ ///
+ /// Redacts access and ID token data from a log message if found.
+ ///
+ private static string RedactTokenValues(string message)
+ {
+ try
+ {
+ var match = Regex.Match(message, @"({.*})");
+ if (match.Success)
+ {
+ var jsonPart = match.Groups[1].Value;
+ var response = JsonUtility.FromJson(jsonPart);
+ if (response?.responseFor is PassportFunction.GET_ACCESS_TOKEN or PassportFunction.GET_ID_TOKEN && !string.IsNullOrEmpty(response.result))
+ {
+ response.result = "[REDACTED]";
+ return message.Replace(jsonPart, JsonUtility.ToJson(response));
+ }
+ }
+ }
+ catch (Exception)
+ {
+ // ignored
+ }
+
+ return message;
+ }
+
private PassportImpl GetPassportImpl()
{
if (passportImpl != null)
diff --git a/src/Packages/Passport/Runtime/ThirdParty/UnityWebBrowser/dev.voltstro.unitywebbrowser@2.2.5/Runtime/Logging/DefaultUnityWebBrowserLogger.cs b/src/Packages/Passport/Runtime/ThirdParty/UnityWebBrowser/dev.voltstro.unitywebbrowser@2.2.5/Runtime/Logging/DefaultUnityWebBrowserLogger.cs
index 77582774..43ca8aa2 100644
--- a/src/Packages/Passport/Runtime/ThirdParty/UnityWebBrowser/dev.voltstro.unitywebbrowser@2.2.5/Runtime/Logging/DefaultUnityWebBrowserLogger.cs
+++ b/src/Packages/Passport/Runtime/ThirdParty/UnityWebBrowser/dev.voltstro.unitywebbrowser@2.2.5/Runtime/Logging/DefaultUnityWebBrowserLogger.cs
@@ -5,6 +5,7 @@
//
// This project is under the MIT license. See the LICENSE.md file for more details.
+using System;
using UnityEngine;
namespace VoltstroStudios.UnityWebBrowser.Logging
@@ -17,25 +18,42 @@ public sealed class DefaultUnityWebBrowserLogger : IWebBrowserLogger
private const string LoggingTag = "[UWB]";
private readonly ILogger logger;
-
- public DefaultUnityWebBrowserLogger()
+
+ ///
+ /// A function that defines how sensitive data should be redacted.
+ /// If null, no redaction is applied.
+ ///
+ public Func? redactionHandler;
+
+ public DefaultUnityWebBrowserLogger(Func? redactionHandler = null)
{
logger = UnityEngine.Debug.unityLogger;
+ this.redactionHandler = redactionHandler;
}
public void Debug(object message)
{
- logger.Log(LogType.Log, LoggingTag, message);
+ logger.Log(LogType.Log, LoggingTag, redactIfRequired(message));
}
public void Warn(object message)
{
- logger.LogWarning(LoggingTag, message);
+ logger.LogWarning(LoggingTag, redactIfRequired(message));
}
public void Error(object message)
{
- logger.LogError(LoggingTag, message);
+ logger.LogError(LoggingTag, redactIfRequired(message));
+ }
+
+ private object redactIfRequired(object message)
+ {
+ if (redactionHandler != null && message is string)
+ {
+ return redactionHandler((string)message);
+ }
+
+ return message;
}
}
}
diff --git a/src/Packages/Passport/Runtime/ThirdParty/UnityWebBrowser/dev.voltstro.unitywebbrowser@2.2.5/Runtime/UwbWebView.cs b/src/Packages/Passport/Runtime/ThirdParty/UnityWebBrowser/dev.voltstro.unitywebbrowser@2.2.5/Runtime/UwbWebView.cs
index 80418220..fd9afc20 100644
--- a/src/Packages/Passport/Runtime/ThirdParty/UnityWebBrowser/dev.voltstro.unitywebbrowser@2.2.5/Runtime/UwbWebView.cs
+++ b/src/Packages/Passport/Runtime/ThirdParty/UnityWebBrowser/dev.voltstro.unitywebbrowser@2.2.5/Runtime/UwbWebView.cs
@@ -1,5 +1,6 @@
#if !IMMUTABLE_CUSTOM_BROWSER && (UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN))
+using System;
using System.IO;
using System.Linq;
using System.Net;
@@ -15,6 +16,7 @@
using VoltstroStudios.UnityWebBrowser.Core.Engines;
using VoltstroStudios.UnityWebBrowser.Core.Js;
using VoltstroStudios.UnityWebBrowser.Helper;
+using VoltstroStudios.UnityWebBrowser.Logging;
using VoltstroStudios.UnityWebBrowser.Shared;
using VoltstroStudios.UnityWebBrowser.Shared.Core;
@@ -28,7 +30,7 @@ public class UwbWebView : MonoBehaviour, IWebBrowserClient
private WebBrowserClient? webBrowserClient;
- public async UniTask Init(int engineStartupTimeoutMs)
+ public async UniTask Init(int engineStartupTimeoutMs, bool redactTokensInLogs, Func redactionHandler)
{
GameObject persistentObject = new GameObject("UWB");
WebBrowserNoUi browser = persistentObject.AddComponent();
@@ -49,6 +51,9 @@ public async UniTask Init(int engineStartupTimeoutMs)
_ => LogSeverity.Info
};
+ // Logger
+ webBrowserClient.Logger = new DefaultUnityWebBrowserLogger(redactionHandler: redactTokensInLogs ? redactionHandler : null);
+
// Js
webBrowserClient.jsMethodManager = new JsMethodManager { jsMethodsEnable = true };
webBrowserClient.RegisterJsMethod("callback",