Skip to content

Commit 890e617

Browse files
authored
Smoother OAuth Cancellation Handling + EndSession Prefab_ConnectWallet Option (#187)
1 parent 3c17230 commit 890e617

File tree

5 files changed

+76
-14
lines changed

5 files changed

+76
-14
lines changed

Assets/Thirdweb/Core/Scripts/Browser/AndroidBrowser.cs

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,14 @@ public async Task<BrowserResult> Login(string loginUrl, string customScheme, Can
3939
return new BrowserResult(BrowserStatus.Timeout, null, "The operation timed out.");
4040
}
4141
}
42+
catch (TaskCanceledException)
43+
{
44+
return new BrowserResult(BrowserStatus.UserCanceled, null, "The operation was cancelled.");
45+
}
46+
catch (Exception ex)
47+
{
48+
return new BrowserResult(BrowserStatus.UnknownError, null, $"An error occurred: {ex.Message}");
49+
}
4250
finally
4351
{
4452
Application.deepLinkActivated -= OnDeepLinkActivated;
@@ -47,17 +55,17 @@ public async Task<BrowserResult> Login(string loginUrl, string customScheme, Can
4755

4856
private void OpenURL(string url)
4957
{
50-
AndroidJavaClass thirdwebActivityClass = new("com.unity3d.player.UnityPlayer");
51-
AndroidJavaObject thirdwebActivity = thirdwebActivityClass.GetStatic<AndroidJavaObject>("currentActivity");
52-
thirdwebActivity.Call("OpenCustomTab", url);
58+
AndroidJavaClass unityPlayer = new("com.unity3d.player.UnityPlayer");
59+
AndroidJavaObject activity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
60+
activity.Call("OpenCustomTab", url);
5361
}
5462

5563
private void OnDeepLinkActivated(string url)
5664
{
57-
if (!url.StartsWith(_customScheme))
65+
if (_taskCompletionSource.Task.IsCanceled || !url.StartsWith(_customScheme))
5866
return;
5967

60-
_taskCompletionSource.SetResult(new BrowserResult(BrowserStatus.Success, url));
68+
_taskCompletionSource.TrySetResult(new BrowserResult(BrowserStatus.Success, url));
6169
}
6270
}
6371
}

Assets/Thirdweb/Core/Scripts/Browser/StandaloneBrowser.cs

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public class StandaloneBrowser : IThirdwebBrowser
1212
{
1313
private TaskCompletionSource<BrowserResult> _taskCompletionSource;
1414

15+
private readonly HttpListener httpListener = new();
16+
1517
private readonly string closePageResponse =
1618
@"
1719
<html>
@@ -57,14 +59,17 @@ public async Task<BrowserResult> Login(string loginUrl, string redirectUrl, Canc
5759
cancellationToken.Register(() =>
5860
{
5961
_taskCompletionSource?.TrySetCanceled();
62+
StopHttpListener();
6063
});
6164

62-
using var httpListener = new HttpListener();
63-
6465
try
6566
{
6667
redirectUrl = AddForwardSlashIfNecessary(redirectUrl);
67-
httpListener.Prefixes.Add(redirectUrl);
68+
if (httpListener.Prefixes.Count == 0 || !httpListener.Prefixes.Contains(redirectUrl))
69+
{
70+
httpListener.Prefixes.Clear();
71+
httpListener.Prefixes.Add(redirectUrl);
72+
}
6873
httpListener.Start();
6974
httpListener.BeginGetContext(IncomingHttpRequest, httpListener);
7075

@@ -80,15 +85,35 @@ public async Task<BrowserResult> Login(string loginUrl, string redirectUrl, Canc
8085
return new BrowserResult(BrowserStatus.Timeout, null, "The operation timed out.");
8186
}
8287
}
88+
catch (TaskCanceledException)
89+
{
90+
return new BrowserResult(BrowserStatus.UserCanceled, null, "The operation was cancelled.");
91+
}
92+
catch (Exception ex)
93+
{
94+
return new BrowserResult(BrowserStatus.UnknownError, null, $"An error occurred: {ex.Message}");
95+
}
8396
finally
97+
{
98+
StopHttpListener();
99+
}
100+
}
101+
102+
private void StopHttpListener()
103+
{
104+
if (httpListener != null && httpListener.IsListening)
84105
{
85106
httpListener.Stop();
107+
httpListener.Close();
86108
}
87109
}
88110

89111
private void IncomingHttpRequest(IAsyncResult result)
90112
{
91113
var httpListener = (HttpListener)result.AsyncState;
114+
if (!httpListener.IsListening)
115+
return;
116+
92117
var httpContext = httpListener.EndGetContext(result);
93118
var httpRequest = httpContext.Request;
94119
var httpResponse = httpContext.Response;
@@ -104,10 +129,9 @@ private void IncomingHttpRequest(IAsyncResult result)
104129

105130
private string AddForwardSlashIfNecessary(string url)
106131
{
107-
string forwardSlash = "/";
108-
if (!url.EndsWith(forwardSlash))
132+
if (!url.EndsWith("/"))
109133
{
110-
url += forwardSlash;
134+
url += "/";
111135
}
112136
return url;
113137
}

Assets/Thirdweb/Core/Scripts/WalletsUI/InAppWalletUI.cs

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
using System.Linq;
1313
using System.Collections.Generic;
1414
using UnityEngine.Events;
15+
using System.Threading;
1516

1617
namespace Thirdweb.Wallets
1718
{
@@ -37,6 +38,7 @@ public class InAppWalletUI : MonoBehaviour
3738
protected Exception _exception;
3839
protected string _callbackUrl;
3940
protected string _customScheme;
41+
protected CancellationTokenSource _cancellationTokenSource;
4042

4143
#endregion
4244

@@ -141,8 +143,16 @@ public virtual async Task<User> Connect(EmbeddedWallet embeddedWallet, string em
141143
return _user;
142144
}
143145

146+
[ContextMenu("Cancel")]
144147
public virtual void Cancel()
145148
{
149+
if (_cancellationTokenSource != null && !_cancellationTokenSource.IsCancellationRequested)
150+
{
151+
_cancellationTokenSource.Cancel();
152+
_cancellationTokenSource.Dispose();
153+
_cancellationTokenSource = null;
154+
}
155+
146156
_exception = new UnityException("User cancelled");
147157
}
148158

@@ -285,11 +295,27 @@ public virtual async Task LoginWithOauth(string authProviderStr)
285295

286296
string redirectUrl = Application.isMobilePlatform ? _customScheme : "http://localhost:8789/";
287297
CrossPlatformBrowser browser = new();
288-
var browserResult = await browser.Login(loginUrl, redirectUrl);
289-
if (browserResult.status != BrowserStatus.Success)
298+
_cancellationTokenSource?.Cancel();
299+
_cancellationTokenSource?.Dispose();
300+
_cancellationTokenSource = new CancellationTokenSource();
301+
var browserResult = await browser.Login(loginUrl, redirectUrl, _cancellationTokenSource.Token);
302+
303+
if (browserResult.status == BrowserStatus.UserCanceled)
304+
{
305+
_cancellationTokenSource?.Dispose();
306+
_cancellationTokenSource = null;
307+
ThirdwebDebug.LogWarning("User cancelled login");
308+
return;
309+
}
310+
else if (browserResult.status != BrowserStatus.Success)
311+
{
290312
_exception = new UnityException($"Failed to login with {authProviderStr}: {browserResult.status} | {browserResult.error}");
313+
return;
314+
}
291315
else
316+
{
292317
_callbackUrl = browserResult.callbackUrl;
318+
}
293319

294320
await new WaitUntil(() => _callbackUrl != null);
295321

Assets/Thirdweb/Examples/Prefabs/Prefab_ConnectWallet.prefab

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4788,6 +4788,7 @@ MonoBehaviour:
47884788
m_EditorClassIdentifier:
47894789
enabledWalletProviders: 07000000000000000100000002000000060000000300000004000000
47904790
useSmartWallets: 0
4791+
endSessionOnDisconnect: 0
47914792
onStart:
47924793
m_PersistentCalls:
47934794
m_Calls:

Assets/Thirdweb/Examples/Scripts/Prefabs/Prefab_ConnectWallet.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,9 @@ public class WalletProviderUIDictionary : SerializableDictionaryBase<WalletProvi
3636
[Header("Use ERC-4337 (Account Abstraction) compatible smart wallets.\nEnabling this will connect user to the associated smart wallet as per your ThirwebManager settings.")]
3737
public bool useSmartWallets = false;
3838

39+
[Header("End session on disconnect. If enabled, user will have to re-authenticate on next connect.")]
40+
public bool endSessionOnDisconnect = false;
41+
3942
[Header("Events")]
4043
public UnityEvent onStart;
4144
public UnityEvent<WalletConnection> onConnectionRequested;
@@ -165,7 +168,7 @@ public async void Disconnect()
165168
{
166169
_address = null;
167170
_password = null;
168-
await ThirdwebManager.Instance.SDK.Wallet.Disconnect(endSession: false);
171+
await ThirdwebManager.Instance.SDK.Wallet.Disconnect(endSession: endSessionOnDisconnect);
169172
onDisconnected.Invoke();
170173
}
171174
catch (System.Exception e)

0 commit comments

Comments
 (0)