Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 18 additions & 17 deletions sample/Assets/Scripts/Passport/Login/LoginScript.cs
Original file line number Diff line number Diff line change
Expand Up @@ -27,51 +27,52 @@ void Start()
ShowOutput("Passport Instance is null");
}

// Set up button listeners if buttons are assigned
if (DefaultLoginButton != null) DefaultLoginButton.onClick.AddListener(() => Login(DirectLoginMethod.None));
if (GoogleLoginButton != null) GoogleLoginButton.onClick.AddListener(() => Login(DirectLoginMethod.Google));
if (AppleLoginButton != null) AppleLoginButton.onClick.AddListener(() => Login(DirectLoginMethod.Apple));
if (FacebookLoginButton != null) FacebookLoginButton.onClick.AddListener(() => Login(DirectLoginMethod.Facebook));
// Set up button listeners using DirectLoginOptions
if (DefaultLoginButton != null) DefaultLoginButton.onClick.AddListener(() => Login(new DirectLoginOptions()));
if (GoogleLoginButton != null) GoogleLoginButton.onClick.AddListener(() => Login(new DirectLoginOptions(DirectLoginMethod.Google)));
if (AppleLoginButton != null) AppleLoginButton.onClick.AddListener(() => Login(new DirectLoginOptions(DirectLoginMethod.Apple)));
if (FacebookLoginButton != null) FacebookLoginButton.onClick.AddListener(() => Login(new DirectLoginOptions(DirectLoginMethod.Facebook)));
}

/// <summary>
/// Logs into Passport using the default auth method.
/// </summary>
public async void Login()
{
await LoginAsync(DirectLoginMethod.None);
await LoginAsync(new DirectLoginOptions());
}

/// <summary>
/// Logs into Passport using the specified direct login method.
/// Logs into Passport using the specified direct login options.
/// </summary>
/// <param name="directLoginMethod">The direct login method to use (Google, Apple, Facebook, or None for default)</param>
public async void Login(DirectLoginMethod directLoginMethod)
/// <param name="directLoginOptions">The direct login options</param>
public async void Login(DirectLoginOptions directLoginOptions)
{
await LoginAsync(directLoginMethod);
await LoginAsync(directLoginOptions);
}

/// <summary>
/// Internal async method that performs the actual login logic.
/// </summary>
/// <param name="directLoginMethod">The direct login method to use</param>
private async System.Threading.Tasks.Task LoginAsync(DirectLoginMethod directLoginMethod)
/// <param name="directLoginOptions">The direct login options</param>
private async System.Threading.Tasks.Task LoginAsync(DirectLoginOptions directLoginOptions)
{
try
{
string methodName = directLoginMethod == DirectLoginMethod.None ? "default" : directLoginMethod.ToString();
ShowOutput($"Logging in with {methodName} method...");
string directLoginMethod = directLoginOptions.directLoginMethod.ToString().ToLower();

bool success = await Passport.Login(useCachedSession: false, directLoginMethod: directLoginMethod);
ShowOutput($"Logging in with {directLoginMethod} method...");

bool success = await Passport.Login(useCachedSession: false, directLoginOptions: directLoginOptions);

if (success)
{
ShowOutput($"Successfully logged in with {methodName}");
ShowOutput($"Successfully logged in with {directLoginMethod}");
SceneManager.LoadScene("AuthenticatedScene");
}
else
{
ShowOutput($"Failed to log in with {methodName}");
ShowOutput($"Failed to log in with {directLoginMethod}");
}
}
catch (OperationCanceledException ex)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@
namespace Immutable.Passport.Model
{
/// <summary>
/// Enum for direct login methods supported by Passport.
/// Enum representing direct login methods for authentication providers.
/// </summary>
[Serializable]
public enum DirectLoginMethod
{
None,
Email,
Google,
Apple,
Facebook
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
using System;

namespace Immutable.Passport.Model
{
/// <summary>
/// Structure representing direct login options for authentication.
/// Can be used for social login (google, apple, facebook) or email login.
/// </summary>
[Serializable]
public class DirectLoginOptions
{
/// <summary>
/// Authentication method.
/// </summary>
public DirectLoginMethod directLoginMethod = DirectLoginMethod.Email;

/// <summary>
/// Email address for email-based authentication (only used when directLoginMethod is Email).
/// </summary>
public string email;

/// <summary>
/// Default constructor.
/// </summary>
public DirectLoginOptions()
{
directLoginMethod = DirectLoginMethod.Email;
email = null;
}

/// <summary>
/// Constructor with method and email.
/// </summary>
/// <param name="loginMethod">The direct login method</param>
/// <param name="emailAddress">The email address (optional)</param>
public DirectLoginOptions(DirectLoginMethod loginMethod, string emailAddress = null)
{
directLoginMethod = loginMethod;
email = emailAddress;
}

/// <summary>
/// Checks if the email is valid and should be included in requests.
/// </summary>
/// <returns>True if email is valid for email method</returns>
public bool IsEmailValid()
{
return directLoginMethod == DirectLoginMethod.Email && !string.IsNullOrEmpty(email);
}
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -14,19 +14,19 @@ internal class GetPKCEAuthUrlRequest
public bool isConnectImx;

/// <summary>
/// The direct login method to use for authentication.
/// The direct login options for authentication.
/// </summary>
public string directLoginMethod;
public DirectLoginOptions directLoginOptions;

/// <summary>
/// Creates a new GetPKCEAuthUrlRequest.
/// Creates a new GetPKCEAuthUrlRequest with DirectLoginOptions.
/// </summary>
/// <param name="isConnectImx">Whether this is a connect to IMX operation</param>
/// <param name="directLoginMethod">The direct login method to use</param>
public GetPKCEAuthUrlRequest(bool isConnectImx, DirectLoginMethod directLoginMethod)
/// <param name="directLoginOptions">The direct login options to use</param>
public GetPKCEAuthUrlRequest(bool isConnectImx, DirectLoginOptions directLoginOptions)
{
this.isConnectImx = isConnectImx;
this.directLoginMethod = directLoginMethod == DirectLoginMethod.None ? null : directLoginMethod.ToString().ToLower();
this.directLoginOptions = directLoginOptions;
}
}
}
30 changes: 23 additions & 7 deletions src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public class PassportImpl
private readonly PassportAnalytics _analytics = new();

private bool _pkceLoginOnly; // Used to differentiate between a login and connect
private DirectLoginMethod _directLoginMethod; // Store the direct login method for current operation
private DirectLoginOptions _directLoginOptions; // Store the direct login options for current operation
private UniTaskCompletionSource<bool>? _pkceCompletionSource;
private string _redirectUri;
private string _logoutRedirectUri;
Expand Down Expand Up @@ -98,7 +98,7 @@ public void SetCallTimeout(int ms)
_communicationsManager.SetCallTimeout(ms);
}

public UniTask<bool> Login(bool useCachedSession = false, DirectLoginMethod directLoginMethod = DirectLoginMethod.None)
public UniTask<bool> Login(bool useCachedSession = false, DirectLoginOptions directLoginOptions = null)
{
if (useCachedSession)
{
Expand All @@ -113,7 +113,7 @@ public UniTask<bool> Login(bool useCachedSession = false, DirectLoginMethod dire
var task = new UniTaskCompletionSource<bool>();
_pkceCompletionSource = task;
_pkceLoginOnly = true;
_directLoginMethod = directLoginMethod;
_directLoginOptions = directLoginOptions;
#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
WindowsDeepLink.Initialise(_redirectUri, OnDeepLinkActivated);
#endif
Expand Down Expand Up @@ -163,7 +163,7 @@ private async UniTask<bool> Relogin()
return false;
}

public async UniTask<bool> ConnectImx(bool useCachedSession = false, DirectLoginMethod directLoginMethod = DirectLoginMethod.None)
public async UniTask<bool> ConnectImx(bool useCachedSession = false, DirectLoginOptions directLoginOptions = null)
{
if (useCachedSession)
{
Expand All @@ -189,7 +189,7 @@ public async UniTask<bool> ConnectImx(bool useCachedSession = false, DirectLogin
UniTaskCompletionSource<bool> task = new UniTaskCompletionSource<bool>();
_pkceCompletionSource = task;
_pkceLoginOnly = false;
_directLoginMethod = directLoginMethod;
_directLoginOptions = directLoginOptions;

#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
WindowsDeepLink.Initialise(_redirectUri, OnDeepLinkActivated);
Expand Down Expand Up @@ -275,8 +275,24 @@ private async UniTask LaunchAuthUrl()
{
try
{
var request = new GetPKCEAuthUrlRequest(!_pkceLoginOnly, _directLoginMethod);
var callResponse = await _communicationsManager.Call(PassportFunction.GET_PKCE_AUTH_URL, JsonUtility.ToJson(request));
// Create the request JSON manually to ensure proper serialization
var requestJson = $"{{\"isConnectImx\":{(!_pkceLoginOnly).ToString().ToLower()}";

if (_directLoginOptions != null)
{
requestJson += $",\"directLoginOptions\":{{\"directLoginMethod\":\"{_directLoginOptions.directLoginMethod.ToString().ToLower()}\"";

if (_directLoginOptions.IsEmailValid())
{
requestJson += $",\"email\":\"{_directLoginOptions.email}\"";
}

requestJson += "}";
}

requestJson += "}";

var callResponse = await _communicationsManager.Call(PassportFunction.GET_PKCE_AUTH_URL, requestJson);
var response = callResponse.OptDeserializeObject<StringResponse>();

if (response != null && response.success == true && response.result != null)
Expand Down
12 changes: 6 additions & 6 deletions src/Packages/Passport/Runtime/Scripts/Public/Passport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -292,25 +292,25 @@ public void SetCallTimeout(int ms)
/// Logs into Passport using Authorisation Code Flow with Proof Key for Code Exchange (PKCE).
/// This opens the user's default browser on desktop or an in-app browser on mobile.
/// <param name="useCachedSession">If true, Passport will attempt to re-authenticate the player using stored credentials. If re-authentication fails, it won't automatically prompt the user to log in again.</param>
/// <param name="directLoginMethod">Optional direct login method to use (google, apple, facebook). If None, the user will see the standard login page.
/// <param name="directLoginOptions">Direct login options for authentication (defaults to email method).
/// </summary>
/// <returns>
/// Returns true if login is successful, otherwise false.
/// </returns>
public async UniTask<bool> Login(bool useCachedSession = false, DirectLoginMethod directLoginMethod = DirectLoginMethod.None)
public async UniTask<bool> Login(bool useCachedSession = false, DirectLoginOptions directLoginOptions = null)
{
return await GetPassportImpl().Login(useCachedSession, directLoginMethod);
return await GetPassportImpl().Login(useCachedSession, directLoginOptions);
}

/// <summary>
/// Logs the user into Passport using Authorisation Code Flow with Proof Key for Code Exchange (PKCE) and sets up the Immutable X provider.
/// This opens the user's default browser on desktop or an in-app browser on mobile.
/// <param name="useCachedSession">If true, Passport will attempt to re-authenticate the player using stored credentials. If re-authentication fails, it won't automatically prompt the user to log in again.</param>
/// <param name="directLoginMethod">Optional direct login method to use (google, apple, facebook). If None, the user will see the standard login page.
/// <param name="directLoginOptions">Direct login options for authentication (defaults to email method).
/// </summary>
public async UniTask<bool> ConnectImx(bool useCachedSession = false, DirectLoginMethod directLoginMethod = DirectLoginMethod.None)
public async UniTask<bool> ConnectImx(bool useCachedSession = false, DirectLoginOptions directLoginOptions = null)
{
return await GetPassportImpl().ConnectImx(useCachedSession, directLoginMethod);
return await GetPassportImpl().ConnectImx(useCachedSession, directLoginOptions);
}

/// <summary>
Expand Down
Loading