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
{