You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
160 lines
6.0 KiB
C#
160 lines
6.0 KiB
C#
#if UNITY_IOS && !UNITY_EDITOR
|
|
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using AOT;
|
|
|
|
using System.Runtime.InteropServices;
|
|
|
|
namespace Thirdweb.Unity
|
|
{
|
|
public class ASWebAuthenticationSession : IDisposable
|
|
{
|
|
private static readonly Dictionary<IntPtr, ASWebAuthenticationSessionCompletionHandler> CompletionCallbacks = new();
|
|
|
|
private IntPtr _sessionPtr;
|
|
|
|
public bool prefersEphemeralWebBrowserSession
|
|
{
|
|
get => Thirdweb_ASWebAuthenticationSession_GetPrefersEphemeralWebBrowserSession(_sessionPtr) == 1;
|
|
set => Thirdweb_ASWebAuthenticationSession_SetPrefersEphemeralWebBrowserSession(_sessionPtr, value ? 1 : 0);
|
|
}
|
|
|
|
public ASWebAuthenticationSession(string url, string callbackUrlScheme, ASWebAuthenticationSessionCompletionHandler completionHandler)
|
|
{
|
|
_sessionPtr = Thirdweb_ASWebAuthenticationSession_InitWithURL(url, callbackUrlScheme, OnAuthenticationSessionCompleted);
|
|
|
|
CompletionCallbacks.Add(_sessionPtr, completionHandler);
|
|
}
|
|
|
|
public bool Start()
|
|
{
|
|
return Thirdweb_ASWebAuthenticationSession_Start(_sessionPtr) == 1;
|
|
}
|
|
|
|
public void Cancel()
|
|
{
|
|
Thirdweb_ASWebAuthenticationSession_Cancel(_sessionPtr);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
CompletionCallbacks.Remove(_sessionPtr);
|
|
_sessionPtr = IntPtr.Zero;
|
|
}
|
|
|
|
private const string DllName = "__Internal";
|
|
|
|
[DllImport(DllName)]
|
|
private static extern IntPtr Thirdweb_ASWebAuthenticationSession_InitWithURL(string url, string callbackUrlScheme, AuthenticationSessionCompletedCallback completionHandler);
|
|
|
|
[DllImport(DllName)]
|
|
private static extern int Thirdweb_ASWebAuthenticationSession_Start(IntPtr session);
|
|
|
|
[DllImport(DllName)]
|
|
private static extern void Thirdweb_ASWebAuthenticationSession_Cancel(IntPtr session);
|
|
|
|
[DllImport(DllName)]
|
|
private static extern int Thirdweb_ASWebAuthenticationSession_GetPrefersEphemeralWebBrowserSession(IntPtr session);
|
|
|
|
[DllImport(DllName)]
|
|
private static extern void Thirdweb_ASWebAuthenticationSession_SetPrefersEphemeralWebBrowserSession(IntPtr session, int enable);
|
|
|
|
public delegate void ASWebAuthenticationSessionCompletionHandler(string callbackUrl, ASWebAuthenticationSessionError error);
|
|
|
|
private delegate void AuthenticationSessionCompletedCallback(IntPtr session, string callbackUrl, int errorCode, string errorMessage);
|
|
|
|
[MonoPInvokeCallback(typeof(AuthenticationSessionCompletedCallback))]
|
|
private static void OnAuthenticationSessionCompleted(IntPtr session, string callbackUrl, int errorCode, string errorMessage)
|
|
{
|
|
if (CompletionCallbacks.TryGetValue(session, out var callback))
|
|
{
|
|
callback?.Invoke(callbackUrl, new ASWebAuthenticationSessionError((ASWebAuthenticationSessionErrorCode)errorCode, errorMessage));
|
|
}
|
|
}
|
|
}
|
|
|
|
public class IOSBrowser : IThirdwebBrowser
|
|
{
|
|
private TaskCompletionSource<BrowserResult> _taskCompletionSource;
|
|
|
|
public bool prefersEphemeralWebBrowserSession { get; set; } = false;
|
|
|
|
public async Task<BrowserResult> Login(ThirdwebClient client, string loginUrl, string redirectUrl, Action<string> browserOpenAction, CancellationToken cancellationToken = default)
|
|
{
|
|
if (string.IsNullOrEmpty(loginUrl))
|
|
throw new ArgumentNullException(nameof(loginUrl));
|
|
|
|
if (string.IsNullOrEmpty(redirectUrl))
|
|
throw new ArgumentNullException(nameof(redirectUrl));
|
|
|
|
_taskCompletionSource = new TaskCompletionSource<BrowserResult>();
|
|
|
|
redirectUrl = redirectUrl.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries)[0];
|
|
|
|
using var authenticationSession = new ASWebAuthenticationSession(loginUrl, redirectUrl, AuthenticationSessionCompletionHandler);
|
|
authenticationSession.prefersEphemeralWebBrowserSession = prefersEphemeralWebBrowserSession;
|
|
|
|
cancellationToken.Register(() =>
|
|
{
|
|
_taskCompletionSource?.TrySetCanceled();
|
|
});
|
|
|
|
try
|
|
{
|
|
if (!authenticationSession.Start())
|
|
{
|
|
_taskCompletionSource.SetResult(new BrowserResult(BrowserStatus.UnknownError, "Browser could not be started."));
|
|
}
|
|
|
|
return await _taskCompletionSource.Task;
|
|
}
|
|
catch (TaskCanceledException)
|
|
{
|
|
authenticationSession?.Cancel();
|
|
throw;
|
|
}
|
|
}
|
|
|
|
private void AuthenticationSessionCompletionHandler(string callbackUrl, ASWebAuthenticationSessionError error)
|
|
{
|
|
if (error.code == ASWebAuthenticationSessionErrorCode.None)
|
|
{
|
|
_taskCompletionSource.SetResult(new BrowserResult(BrowserStatus.Success, callbackUrl));
|
|
}
|
|
else if (error.code == ASWebAuthenticationSessionErrorCode.CanceledLogin)
|
|
{
|
|
_taskCompletionSource.SetResult(new BrowserResult(BrowserStatus.UserCanceled, callbackUrl, error.message));
|
|
}
|
|
else
|
|
{
|
|
_taskCompletionSource.SetResult(new BrowserResult(BrowserStatus.UnknownError, callbackUrl, error.message));
|
|
}
|
|
}
|
|
}
|
|
|
|
public class ASWebAuthenticationSessionError
|
|
{
|
|
public ASWebAuthenticationSessionErrorCode code { get; }
|
|
public string message { get; }
|
|
|
|
public ASWebAuthenticationSessionError(ASWebAuthenticationSessionErrorCode code, string message)
|
|
{
|
|
this.code = code;
|
|
this.message = message;
|
|
}
|
|
}
|
|
|
|
public enum ASWebAuthenticationSessionErrorCode
|
|
{
|
|
None = 0,
|
|
CanceledLogin = 1,
|
|
PresentationContextNotProvided = 2,
|
|
PresentationContextInvalid = 3
|
|
}
|
|
}
|
|
|
|
#endif
|