diff --git a/sample/Assets/Scenes/Passport/SelectAuthMethod.unity b/sample/Assets/Scenes/Passport/SelectAuthMethod.unity index 6051908d..458e1dff 100644 --- a/sample/Assets/Scenes/Passport/SelectAuthMethod.unity +++ b/sample/Assets/Scenes/Passport/SelectAuthMethod.unity @@ -206,7 +206,7 @@ MonoBehaviour: m_TargetGraphic: {fileID: 416242725} m_HandleRect: {fileID: 416242724} m_Direction: 0 - m_Value: 0 + m_Value: 1 m_Size: 1 m_NumberOfSteps: 0 m_OnValueChanged: @@ -1323,7 +1323,7 @@ MonoBehaviour: m_TargetGraphic: {fileID: 167431872} m_HandleRect: {fileID: 167431871} m_Direction: 2 - m_Value: 1 + m_Value: 0 m_Size: 1 m_NumberOfSteps: 0 m_OnValueChanged: @@ -1673,8 +1673,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 1016.24, y: 0} - m_SizeDelta: {x: 1992.48, y: 0} + m_AnchoredPosition: {x: 841.51855, y: 0} + m_SizeDelta: {x: 1643.0371, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &1661390145 MonoBehaviour: @@ -1768,8 +1768,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 1016.24, y: 0} - m_SizeDelta: {x: 1992.48, y: 0} + m_AnchoredPosition: {x: 841.51855, y: 0} + m_SizeDelta: {x: 1643.0371, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &1688502349 MonoBehaviour: diff --git a/sample/Assets/Scripts/Passport/AuthenticatedScript.cs b/sample/Assets/Scripts/Passport/AuthenticatedScript.cs index 587c4e4d..2fce9dff 100644 --- a/sample/Assets/Scripts/Passport/AuthenticatedScript.cs +++ b/sample/Assets/Scripts/Passport/AuthenticatedScript.cs @@ -186,11 +186,9 @@ public async void Logout() try { // Logout using the appropriate logout method - if (SampleAppManager.SupportsPKCE && SampleAppManager.UsePKCE) + if (SampleAppManager.UsePKCE) { -#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL await Passport.LogoutPKCE(); -#endif } else { diff --git a/sample/Assets/Scripts/Passport/SampleAppManager.cs b/sample/Assets/Scripts/Passport/SampleAppManager.cs index 32ec7bb5..75ae157c 100644 --- a/sample/Assets/Scripts/Passport/SampleAppManager.cs +++ b/sample/Assets/Scripts/Passport/SampleAppManager.cs @@ -1,10 +1,5 @@ public static class SampleAppManager { - /// - /// Indicates whether the running platform supports PKCE. - /// - public static bool SupportsPKCE { get; set; } - /// /// Indicates whether the selected authentication method is PKCE. /// diff --git a/sample/Assets/Scripts/Passport/SelectAuthMethodScript.cs b/sample/Assets/Scripts/Passport/SelectAuthMethodScript.cs index 9eec6809..8fe8a861 100644 --- a/sample/Assets/Scripts/Passport/SelectAuthMethodScript.cs +++ b/sample/Assets/Scripts/Passport/SelectAuthMethodScript.cs @@ -16,30 +16,9 @@ public class SelectAuthMethodScript : MonoBehaviour void Start() { - // Determine if PKCE is supported based on the platform - SampleAppManager.SupportsPKCE = IsPKCESupported(); - // WebGL does not support Device Code Auth, so we'll use PKCE by default instead. #if UNITY_WEBGL UsePKCE(); -#else - // If PKCE is not supported, initialise Passport to use Device Code Auth - if (!SampleAppManager.SupportsPKCE) - { - UseDeviceCodeAuth(); - } -#endif - } - - /// - /// Checks if the current platform supports PKCE authentication. - /// - private bool IsPKCESupported() - { -#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL - return true; -#else - return false; #endif } diff --git a/sample/Assets/Scripts/Passport/UnauthenticatedScript.cs b/sample/Assets/Scripts/Passport/UnauthenticatedScript.cs index f86f12de..2014b037 100644 --- a/sample/Assets/Scripts/Passport/UnauthenticatedScript.cs +++ b/sample/Assets/Scripts/Passport/UnauthenticatedScript.cs @@ -67,11 +67,9 @@ public async void Login() try { // Login using the appropriate login method - if (SampleAppManager.SupportsPKCE && SampleAppManager.UsePKCE) + if (SampleAppManager.UsePKCE) { -#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL await Passport.LoginPKCE(); -#endif } else { @@ -109,11 +107,9 @@ public async void Connect() try { // Login and connect to IMX using the appropriate connect method - if (SampleAppManager.SupportsPKCE && SampleAppManager.UsePKCE) + if (SampleAppManager.UsePKCE) { -#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL await Passport.ConnectImxPKCE(); -#endif } else { @@ -206,11 +202,9 @@ private async UniTask Logout() try { // Logout using the appropriate logout method - if (SampleAppManager.SupportsPKCE && SampleAppManager.UsePKCE) + if (SampleAppManager.UsePKCE) { -#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL await Passport.LogoutPKCE(); -#endif } else { diff --git a/sample/Tests/test/test_windows.py b/sample/Tests/test/test_windows.py index 8918abac..aeef3358 100644 --- a/sample/Tests/test/test_windows.py +++ b/sample/Tests/test/test_windows.py @@ -20,6 +20,9 @@ def tearDownClass(cls): stop_sample_app() def test_1_device_code_login(self): + # Select use device code auth + self.altdriver.find_object(By.NAME, "DeviceCodeAuth").tap() + # Wait for unauthenticated screen self.altdriver.wait_for_current_scene_to_be("UnauthenticatedScene") @@ -48,9 +51,12 @@ def test_1_device_code_login(self): if attempt == 0: # Reset app - # Relogin + # Relogin (optional: only if the button is present) print("Try reset the app and log out once...") - self.altdriver.wait_for_object(By.NAME, "ReloginBtn").tap() + try: + self.altdriver.wait_for_object(By.NAME, "ReloginBtn").tap() + except Exception as e: + print("ReloginBtn not found, skipping relogin step. User may already be in AuthenticatedScene.") # Wait for authenticated screen self.altdriver.wait_for_current_scene_to_be("AuthenticatedScene") @@ -95,6 +101,9 @@ def test_6_relogin(self): self.altdriver = AltDriver() time.sleep(5) + # Select use device code auth + self.altdriver.find_object(By.NAME, "DeviceCodeAuth").tap() + # Relogin print("Re-logging in...") self.altdriver.wait_for_object(By.NAME, "ReloginBtn").tap() @@ -124,6 +133,9 @@ def test_7_reconnect_device_code_connect_imx(self): self.altdriver = AltDriver() time.sleep(5) + # Select use device code auth + self.altdriver.find_object(By.NAME, "DeviceCodeAuth").tap() + # Reconnect print("Reconnecting...") self.altdriver.wait_for_object(By.NAME, "ReconnectBtn").tap() diff --git a/src/Packages/Passport/Private.meta b/src/Packages/Passport/Private.meta new file mode 100644 index 00000000..45247054 --- /dev/null +++ b/src/Packages/Passport/Private.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: c7a5ad71040aa964b890d5cc82c42217 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Packages/Passport/Private/Helpers.meta b/src/Packages/Passport/Private/Helpers.meta new file mode 100644 index 00000000..8b02725b --- /dev/null +++ b/src/Packages/Passport/Private/Helpers.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a6136de6bac990f40bd647693397e104 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/src/Packages/Passport/Runtime/Scripts/Private/Helpers/WindowsDeepLink.cs b/src/Packages/Passport/Runtime/Scripts/Private/Helpers/WindowsDeepLink.cs new file mode 100644 index 00000000..1c55a719 --- /dev/null +++ b/src/Packages/Passport/Runtime/Scripts/Private/Helpers/WindowsDeepLink.cs @@ -0,0 +1,375 @@ +#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) +using System; +using System.IO; +using System.Runtime.InteropServices; +using UnityEditor; +using UnityEngine; +using Immutable.Passport.Core.Logging; + +#nullable enable +namespace Immutable.Passport.Helpers +{ + public class WindowsDeepLink : MonoBehaviour + { + private const string RegistryDeepLinkName = "deeplink"; + + private static WindowsDeepLink? _instance; + private Action? _callback; + private string? _protocolName; + + // P/Invoke declarations + private const uint HKEY_CURRENT_USER = 0x80000001; + private const uint KEY_READ = 0x20019; + private const uint KEY_WRITE = 0x20006; + private const uint KEY_READ_WRITE = KEY_READ | KEY_WRITE; + private const uint REG_SZ = 1; + + [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern int RegCreateKeyEx( + UIntPtr hKey, + string lpSubKey, + int Reserved, + string lpClass, + uint dwOptions, + uint samDesired, + IntPtr lpSecurityAttributes, + out UIntPtr phkResult, + out uint lpdwDisposition); + + [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern int RegSetValueEx( + UIntPtr hKey, + string lpValueName, + int Reserved, + uint dwType, + string lpData, + uint cbData); + + [DllImport("advapi32.dll", SetLastError = true)] + private static extern int RegCloseKey(UIntPtr hKey); + + [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern int RegDeleteTree(UIntPtr hKey, string lpSubKey); + + [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern int RegOpenKeyEx( + UIntPtr hKey, + string subKey, + uint options, + uint samDesired, + out UIntPtr phkResult); + + [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] + private static extern int RegQueryValueEx( + UIntPtr hKey, + string lpValueName, + IntPtr lpReserved, + ref uint lpType, + byte[] lpData, + ref uint lpcbData); + + /// + /// Initialises the Windows deep link handler for a given protocol. + /// + /// The redirect URI containing the protocol to handle (e.g. "immutable://") + /// Callback to invoke when a deep link is received + public static void Initialise(string redirectUri, Action callback) + { + if (_instance == null) + { + _instance = new GameObject(nameof(WindowsDeepLink)).AddComponent(); + DontDestroyOnLoad(_instance.gameObject); + } + + if (string.IsNullOrEmpty(redirectUri)) return; + + // Extract protocol name from URI (e.g. "immutable" from "immutable://") + var protocolName = redirectUri.Split(new[] { "://" }, StringSplitOptions.None)[0]; + _instance._protocolName = protocolName; + _instance._callback = callback; + + // Register protocol and create handler script + RegisterProtocol(protocolName); + CreateCommandScript(protocolName); + } + + private static void CreateCommandScript(string protocolName) + { + // Get path for the command script file + var cmdPath = GetGameExecutablePath(".cmd"); + +#if UNITY_EDITOR_WIN + // Get Unity project and executable paths + var projectPath = Application.dataPath.Replace("/Assets", "").Replace("/", "\\"); + var unityExe = EditorApplication.applicationPath.Replace("/", "\\"); + + // Get path for the log file + var logPath = Path.Combine(Application.persistentDataPath, "deeplink_logs.txt").Replace("/", "\\"); + + string[] scriptLines = + { + "@echo off", + // Store deeplink URI in registry + $"REG ADD \"HKCU\\Software\\Classes\\{protocolName}\" /v \"{RegistryDeepLinkName}\" /t REG_SZ /d %1 /f >nul 2>&1", + "setlocal", + "", + $"set \"PROJECT_PATH={projectPath}\"", + $"set \"LOG_PATH={logPath}\"", + "", + // Create log file + "echo [%date% %time%] Script started > \"%LOG_PATH%\"", + "echo [%date% %time%] Project path: %PROJECT_PATH% >> \"%LOG_PATH%\"", + $"echo [%date% %time%] Unity exe: {unityExe} >> \"%LOG_PATH%\"", + "", + // Find running Unity instance with matching project path + "for /f \"tokens=2 delims==\" %%A in ('wmic process where \"name='Unity.exe'\" get ProcessId /value') do (", + " echo [%date% %time%] Checking Unity process ID: %%A >> \"%LOG_PATH%\"", + " setlocal EnableDelayedExpansion", + " set \"cmdline=\"", + " for /f \"tokens=*\" %%B in ('wmic process where \"ProcessId=%%A\" get CommandLine /value') do (", + " if not \"%%B\"==\"\" set \"cmdline=!cmdline!%%B\"", + " )", + " echo [%date% %time%] Raw command line: !cmdline! >> \"%LOG_PATH%\"", + " echo !cmdline! | findstr /I /C:\"-projectPath\" | findstr /I /C:\"%PROJECT_PATH%\" >nul", + " if not errorlevel 1 (", + " echo [%date% %time%] Found matching Unity process ID: %%A >> \"%LOG_PATH%\"", + " echo [%date% %time%] Command line: !cmdline! >> \"%LOG_PATH%\"", + " powershell -NoProfile -ExecutionPolicy Bypass -Command ^", + " \"$ErrorActionPreference = 'Continue';\" ^", + " \"$wshell = New-Object -ComObject wscript.shell;\" ^", + " \"echo [$(Get-Date)] Attempting to activate process ID: %%A >> \\\"{logPath}\\\";\" ^", + " \"Start-Sleep -Milliseconds 100;\" ^", + " \"$result = $wshell.AppActivate(%%A);\" ^", + " \"echo [$(Get-Date)] AppActivate result: $result >> \\\"{logPath}\\\";\" ^", + " \"if (-not $result) { echo [$(Get-Date)] Failed to activate window >> \\\"{logPath}\\\" }\"", + " if errorlevel 1 echo [%date% %time%] PowerShell error: %errorlevel% >> \"%LOG_PATH%\"", + " endlocal", + " exit /b 0", + " )", + " endlocal", + ")", + "", + // Exit if Unity instance found + "if %errorlevel% equ 0 exit /b 0", + "", + // Start new Unity instance if none found + $"echo [%date% %time%] Starting new Unity instance >> \"%LOG_PATH%\"", + $"start \"\" \"{unityExe}\" -projectPath \"%PROJECT_PATH%\" >nul 2>&1" + }; + + File.WriteAllLines(cmdPath, scriptLines); + PassportLogger.Debug($"Writing script to {cmdPath}"); + PassportLogger.Debug($"Writing logs to {logPath}"); + +#else + // Get game executable path and name + string pathToUnityGame = GetGameExecutablePath(".exe"); + string gameExeName = Path.GetFileName(pathToUnityGame); + + File.WriteAllLines(cmdPath, new[] + { + "@echo off", + // Store deeplink URI in registry + $"REG ADD \"HKCU\\Software\\Classes\\{protocolName}\" /v \"{RegistryDeepLinkName}\" /t REG_SZ /d %1 /f >nul 2>&1", + // Check if game is already running + $"tasklist /FI \"IMAGENAME eq {gameExeName}\" 2>NUL | find /I \"{gameExeName}\" >NUL", + "if %ERRORLEVEL%==0 (", + // Bring existing game window to foreground + " powershell -NoProfile -ExecutionPolicy Bypass -Command ^", + " \"$ErrorActionPreference = 'SilentlyContinue';\" ^", + " \"$wshell = New-Object -ComObject wscript.shell;\" ^", + " \"$process = Get-Process -Name '" + Path.GetFileNameWithoutExtension(gameExeName) + "' -ErrorAction SilentlyContinue;\" ^", + " \"if ($process) { $wshell.AppActivate($process.Id) | Out-Null }\" ^", + " >nul 2>&1 3>&1 4>&1 5>&1", + " exit /b 0", + ") else (", + // Start new game instance if not running + $" start \"\" /b \"{pathToUnityGame}\" %1 >nul 2>&1 3>&1 4>&1 5>&1", + ")" + }); +#endif + } + + private static void RegisterProtocol(string protocolName) + { + PassportLogger.Debug($"Register protocol: {protocolName}"); + + UIntPtr hKey; + uint disposition; + // Create registry key for the protocol + int result = RegCreateKeyEx( + (UIntPtr)HKEY_CURRENT_USER, + $@"Software\Classes\{protocolName}", + 0, + null, + 0, + KEY_READ | KEY_WRITE, + IntPtr.Zero, + out hKey, + out disposition); + + if (result != 0) + { + throw new Exception($"Failed to create PKCE registry key. Error code: {result}"); + } + + // Set URL Protocol value + RegSetValueEx(hKey, "URL Protocol", 0, REG_SZ, string.Empty, 2); + + // Create command subkey + UIntPtr commandKey; + result = RegCreateKeyEx( + hKey, + @"shell\open\command", + 0, + null, + 0, + KEY_READ | KEY_WRITE, + IntPtr.Zero, + out commandKey, + out disposition); + + if (result != 0) + { + RegCloseKey(hKey); + throw new Exception($"Failed to create PKCE command registry key. Error code: {result}"); + } + + // Set command to launch the script with the URI parameter + var scriptLocation = GetGameExecutablePath(".cmd"); + string command = $"\"{scriptLocation}\" \"%1\""; + uint commandSize = (uint)((command.Length + 1) * 2); + + result = RegSetValueEx(commandKey, "", 0, REG_SZ, command, commandSize); + if (result != 0) + { + RegCloseKey(commandKey); + RegCloseKey(hKey); + throw new Exception($"Failed to set PKCE command. Error code: {result}"); + } + + // Clean up registry handles + RegCloseKey(commandKey); + RegCloseKey(hKey); + } + + private static string GetGameExecutablePath(string suffix) + { + var exeName = Application.productName + suffix; +#if UNITY_EDITOR_WIN + // Returns the persistent data path in editor + return Path.Combine(Application.persistentDataPath, exeName).Replace("/", "\\"); +#else + // Returns game root directory in build + var exePath = Application.dataPath.Replace("/Data", "").Replace($"/{Application.productName}_Data", ""); + return Path.Combine(exePath, exeName).Replace("/", "\\"); +#endif + } + + private void OnApplicationFocus(bool hasFocus) + { + // Only handle deeplink when application regains focus + if (!hasFocus) return; + + HandleDeeplink(); + } + + private void HandleDeeplink() + { + // Open registry key for the protocol + string registryPath = $@"Software\Classes\{_protocolName}"; + UIntPtr hKey; + int result = RegOpenKeyEx( + (UIntPtr)HKEY_CURRENT_USER, + registryPath, + 0, + KEY_READ_WRITE, + out hKey); + + if (result != 0) + { + PassportLogger.Error($"Failed to open registry key. Error code: {result}"); + return; + } + + // Get size of deeplink data + uint type = 0; + uint dataSize = 0; + result = RegQueryValueEx(hKey, RegistryDeepLinkName, IntPtr.Zero, ref type, null!, ref dataSize); + + if (result != 0) + { + RegCloseKey(hKey); + PassportLogger.Warn($"Failed to get deeplink data size. Error code: {result}"); + return; + } + + // Read deeplink data + var data = new byte[dataSize]; + result = RegQueryValueEx(hKey, RegistryDeepLinkName, IntPtr.Zero, ref type, data, ref dataSize); + + var callbackInvoked = false; + if (result == 0 && type == REG_SZ) + { + // Convert and validate URI + var uri = System.Text.Encoding.Unicode.GetString(data, 0, (int)dataSize - 2); // Remove null terminator + if (_protocolName != null && !uri.StartsWith(_protocolName)) + { + PassportLogger.Error($"Incorrect prefix uri {uri}"); + } + else + { + // Invoke callback with valid URI + _callback?.Invoke(uri); + callbackInvoked = true; + } + } + else + { + PassportLogger.Warn($"Failed to get registry key. Error code: {result}"); + } + + // Clean up registry handle + RegCloseKey(hKey); + + // Delete registry key if callback was invoked + if (callbackInvoked) + { + result = RegDeleteTree((UIntPtr)HKEY_CURRENT_USER, registryPath); + + if (result != 0) + { + PassportLogger.Warn($"Failed to delete registry key. Error code: {result}"); + } + else + { + PassportLogger.Debug("Successfully deleted registry key."); + } + } + else + { + PassportLogger.Debug("Did not invoke callback so not deleting registry key."); + } + + // Clean up command script + var cmdPath = GetGameExecutablePath(".cmd"); + if (File.Exists(cmdPath)) + { + try + { + File.Delete(cmdPath); + } + catch (Exception ex) + { + PassportLogger.Warn($"Failed to delete script: {ex.Message}"); + } + } + + // Clean up instance + Destroy(gameObject); + _instance = null; + } + } +} +#endif + diff --git a/src/Packages/Passport/Runtime/Scripts/Private/Helpers/WindowsDeepLink.cs.meta b/src/Packages/Passport/Runtime/Scripts/Private/Helpers/WindowsDeepLink.cs.meta new file mode 100644 index 00000000..1c969b86 --- /dev/null +++ b/src/Packages/Passport/Runtime/Scripts/Private/Helpers/WindowsDeepLink.cs.meta @@ -0,0 +1,3 @@ +fileFormatVersion: 2 +guid: f7858bbc79fc486594ed41c9f4abc7b0 +timeCreated: 1742350622 \ No newline at end of file diff --git a/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs b/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs index a48a696a..71079db9 100644 --- a/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs +++ b/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs @@ -103,7 +103,8 @@ public async UniTask Init(string clientId, string environment, string? redirectU Track(PassportAnalytics.EventName.INIT_PASSPORT, success: false); throw new PassportException(initResponse.error ?? "Unable to initialise Passport"); } - else if (deeplink != null) + + if (deeplink != null) { OnDeepLinkActivated(deeplink); } @@ -347,6 +348,9 @@ public UniTask LoginPKCE() UniTaskCompletionSource task = new UniTaskCompletionSource(); pkceCompletionSource = task; pkceLoginOnly = true; +#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) + WindowsDeepLink.Initialise(redirectUri, OnDeepLinkActivated); +#endif _ = LaunchAuthUrl(); return task.Task; } @@ -370,6 +374,11 @@ public UniTask ConnectImxPKCE() UniTaskCompletionSource task = new UniTaskCompletionSource(); pkceCompletionSource = task; pkceLoginOnly = false; + +#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) + WindowsDeepLink.Initialise(redirectUri, OnDeepLinkActivated); +#endif + _ = LaunchAuthUrl(); return task.Task; } @@ -578,6 +587,9 @@ public UniTask LogoutPKCE(bool hardLogout = true) UniTaskCompletionSource task = new UniTaskCompletionSource(); pkceCompletionSource = task; +#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) + WindowsDeepLink.Initialise(logoutRedirectUri, OnDeepLinkActivated); +#endif LaunchLogoutPKCEUrl(hardLogout); return task.Task; } diff --git a/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs b/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs index 7f937b51..a7419bcd 100644 --- a/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs +++ b/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs @@ -310,7 +310,6 @@ public async UniTask ConnectImx(bool useCachedSession = false, long? timeo return await GetPassportImpl().ConnectImx(useCachedSession, timeoutMs); } -#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL /// /// Connects the user into Passport via PKCE auth. /// @@ -329,7 +328,6 @@ public async UniTask ConnectImxPKCE() { return await GetPassportImpl().ConnectImxPKCE(); } -#endif /// /// Gets the wallet address of the logged in user. @@ -352,7 +350,6 @@ public async UniTask Logout(bool hardLogout = true) await GetPassportImpl().Logout(hardLogout); } -#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL /// /// Logs the user out of Passport and removes any stored credentials. /// Recommended to use when logging in using PKCE flow - ConnectImxPKCE() @@ -362,7 +359,6 @@ public async UniTask LogoutPKCE(bool hardLogout = true) { await GetPassportImpl().LogoutPKCE(hardLogout); } -#endif /// /// Checks if credentials exist but does not check if they're valid diff --git a/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/AuthenticatedScript.cs b/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/AuthenticatedScript.cs index 587c4e4d..2fce9dff 100644 --- a/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/AuthenticatedScript.cs +++ b/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/AuthenticatedScript.cs @@ -186,11 +186,9 @@ public async void Logout() try { // Logout using the appropriate logout method - if (SampleAppManager.SupportsPKCE && SampleAppManager.UsePKCE) + if (SampleAppManager.UsePKCE) { -#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL await Passport.LogoutPKCE(); -#endif } else { diff --git a/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/SampleAppManager.cs b/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/SampleAppManager.cs index 32ec7bb5..75ae157c 100644 --- a/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/SampleAppManager.cs +++ b/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/SampleAppManager.cs @@ -1,10 +1,5 @@ public static class SampleAppManager { - /// - /// Indicates whether the running platform supports PKCE. - /// - public static bool SupportsPKCE { get; set; } - /// /// Indicates whether the selected authentication method is PKCE. /// diff --git a/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/SelectAuthMethodScript.cs b/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/SelectAuthMethodScript.cs index 9eec6809..8fe8a861 100644 --- a/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/SelectAuthMethodScript.cs +++ b/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/SelectAuthMethodScript.cs @@ -16,30 +16,9 @@ public class SelectAuthMethodScript : MonoBehaviour void Start() { - // Determine if PKCE is supported based on the platform - SampleAppManager.SupportsPKCE = IsPKCESupported(); - // WebGL does not support Device Code Auth, so we'll use PKCE by default instead. #if UNITY_WEBGL UsePKCE(); -#else - // If PKCE is not supported, initialise Passport to use Device Code Auth - if (!SampleAppManager.SupportsPKCE) - { - UseDeviceCodeAuth(); - } -#endif - } - - /// - /// Checks if the current platform supports PKCE authentication. - /// - private bool IsPKCESupported() - { -#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL - return true; -#else - return false; #endif } diff --git a/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/UnauthenticatedScript.cs b/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/UnauthenticatedScript.cs index f86f12de..2014b037 100644 --- a/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/UnauthenticatedScript.cs +++ b/src/Packages/Passport/Samples~/SamplesScenesScripts/Scripts/Passport/UnauthenticatedScript.cs @@ -67,11 +67,9 @@ public async void Login() try { // Login using the appropriate login method - if (SampleAppManager.SupportsPKCE && SampleAppManager.UsePKCE) + if (SampleAppManager.UsePKCE) { -#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL await Passport.LoginPKCE(); -#endif } else { @@ -109,11 +107,9 @@ public async void Connect() try { // Login and connect to IMX using the appropriate connect method - if (SampleAppManager.SupportsPKCE && SampleAppManager.UsePKCE) + if (SampleAppManager.UsePKCE) { -#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL await Passport.ConnectImxPKCE(); -#endif } else { @@ -206,11 +202,9 @@ private async UniTask Logout() try { // Logout using the appropriate logout method - if (SampleAppManager.SupportsPKCE && SampleAppManager.UsePKCE) + if (SampleAppManager.UsePKCE) { -#if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL await Passport.LogoutPKCE(); -#endif } else {