Skip to content

Commit 03e4a6a

Browse files
feat: add direct login support (#3819)
1 parent 4da30cf commit 03e4a6a

File tree

8 files changed

+857
-76
lines changed

8 files changed

+857
-76
lines changed

sample/Assets/Scenes/Passport/UnauthenticatedScene.unity

Lines changed: 726 additions & 64 deletions
Large diffs are not rendered by default.

sample/Assets/Scripts/Passport/Login/LoginScript.cs

Lines changed: 48 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,16 @@
33
using UnityEngine.UI;
44
using UnityEngine.SceneManagement;
55
using Immutable.Passport;
6+
using Immutable.Passport.Model;
67

78
public class LoginScript : MonoBehaviour
89
{
910
#pragma warning disable CS8618
1011
[SerializeField] private Text Output;
12+
[SerializeField] private Button DefaultLoginButton;
13+
[SerializeField] private Button GoogleLoginButton;
14+
[SerializeField] private Button AppleLoginButton;
15+
[SerializeField] private Button FacebookLoginButton;
1116
private Passport Passport;
1217
#pragma warning restore CS8618
1318

@@ -21,25 +26,61 @@ void Start()
2126
{
2227
ShowOutput("Passport Instance is null");
2328
}
29+
30+
// Set up button listeners if buttons are assigned
31+
if (DefaultLoginButton != null) DefaultLoginButton.onClick.AddListener(() => Login(DirectLoginMethod.None));
32+
if (GoogleLoginButton != null) GoogleLoginButton.onClick.AddListener(() => Login(DirectLoginMethod.Google));
33+
if (AppleLoginButton != null) AppleLoginButton.onClick.AddListener(() => Login(DirectLoginMethod.Apple));
34+
if (FacebookLoginButton != null) FacebookLoginButton.onClick.AddListener(() => Login(DirectLoginMethod.Facebook));
2435
}
2536

2637
/// <summary>
27-
/// Logs into Passport using the selected auth method.
38+
/// Logs into Passport using the default auth method.
2839
/// </summary>
2940
public async void Login()
41+
{
42+
await LoginAsync(DirectLoginMethod.None);
43+
}
44+
45+
/// <summary>
46+
/// Logs into Passport using the specified direct login method.
47+
/// </summary>
48+
/// <param name="directLoginMethod">The direct login method to use (Google, Apple, Facebook, or None for default)</param>
49+
public async void Login(DirectLoginMethod directLoginMethod)
50+
{
51+
await LoginAsync(directLoginMethod);
52+
}
53+
54+
/// <summary>
55+
/// Internal async method that performs the actual login logic.
56+
/// </summary>
57+
/// <param name="directLoginMethod">The direct login method to use</param>
58+
private async System.Threading.Tasks.Task LoginAsync(DirectLoginMethod directLoginMethod)
3059
{
3160
try
3261
{
33-
await Passport.Login();
34-
SceneManager.LoadScene("AuthenticatedScene");
62+
string methodName = directLoginMethod == DirectLoginMethod.None ? "default" : directLoginMethod.ToString();
63+
ShowOutput($"Logging in with {methodName} method...");
64+
65+
bool success = await Passport.Login(useCachedSession: false, directLoginMethod: directLoginMethod);
66+
67+
if (success)
68+
{
69+
ShowOutput($"Successfully logged in with {methodName}");
70+
SceneManager.LoadScene("AuthenticatedScene");
71+
}
72+
else
73+
{
74+
ShowOutput($"Failed to log in with {methodName}");
75+
}
3576
}
3677
catch (OperationCanceledException ex)
3778
{
38-
ShowOutput($"Failed to login: cancelled {ex.Message}\\n{ex.StackTrace}");
79+
ShowOutput($"Login cancelled: {ex.Message}");
3980
}
4081
catch (Exception ex)
4182
{
42-
ShowOutput($"Failed to login: {ex.Message}");
83+
ShowOutput($"Login failed: {ex.Message}");
4384
}
4485
}
4586

@@ -49,5 +90,7 @@ private void ShowOutput(string message)
4990
{
5091
Output.text = message;
5192
}
93+
94+
Debug.Log($"[LoginScript] {message}");
5295
}
5396
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
using System;
2+
3+
namespace Immutable.Passport.Model
4+
{
5+
/// <summary>
6+
/// Enum for direct login methods supported by Passport.
7+
/// </summary>
8+
[Serializable]
9+
public enum DirectLoginMethod
10+
{
11+
None,
12+
Google,
13+
Apple,
14+
Facebook
15+
}
16+
}

src/Packages/Passport/Runtime/Scripts/Private/Model/DirectLoginMethod.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
using System;
2+
3+
namespace Immutable.Passport.Model
4+
{
5+
/// <summary>
6+
/// Request model for getting PKCE authentication URL.
7+
/// </summary>
8+
[Serializable]
9+
internal class GetPKCEAuthUrlRequest
10+
{
11+
/// <summary>
12+
/// Whether this is a connect to IMX operation (true) or just login (false).
13+
/// </summary>
14+
public bool isConnectImx;
15+
16+
/// <summary>
17+
/// The direct login method to use for authentication.
18+
/// </summary>
19+
public string directLoginMethod;
20+
21+
/// <summary>
22+
/// Creates a new GetPKCEAuthUrlRequest.
23+
/// </summary>
24+
/// <param name="isConnectImx">Whether this is a connect to IMX operation</param>
25+
/// <param name="directLoginMethod">The direct login method to use</param>
26+
public GetPKCEAuthUrlRequest(bool isConnectImx, DirectLoginMethod directLoginMethod)
27+
{
28+
this.isConnectImx = isConnectImx;
29+
this.directLoginMethod = directLoginMethod == DirectLoginMethod.None ? null : directLoginMethod.ToString().ToLower();
30+
}
31+
}
32+
}

src/Packages/Passport/Runtime/Scripts/Private/Model/Request/GetPKCEAuthUrlRequest.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ public class PassportImpl
2525
private readonly PassportAnalytics _analytics = new();
2626

2727
private bool _pkceLoginOnly; // Used to differentiate between a login and connect
28+
private DirectLoginMethod _directLoginMethod; // Store the direct login method for current operation
2829
private UniTaskCompletionSource<bool>? _pkceCompletionSource;
2930
private string _redirectUri;
3031
private string _logoutRedirectUri;
@@ -97,7 +98,7 @@ public void SetCallTimeout(int ms)
9798
_communicationsManager.SetCallTimeout(ms);
9899
}
99100

100-
public UniTask<bool> Login(bool useCachedSession = false)
101+
public UniTask<bool> Login(bool useCachedSession = false, DirectLoginMethod directLoginMethod = DirectLoginMethod.None)
101102
{
102103
if (useCachedSession)
103104
{
@@ -112,6 +113,7 @@ public UniTask<bool> Login(bool useCachedSession = false)
112113
var task = new UniTaskCompletionSource<bool>();
113114
_pkceCompletionSource = task;
114115
_pkceLoginOnly = true;
116+
_directLoginMethod = directLoginMethod;
115117
#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
116118
WindowsDeepLink.Initialise(_redirectUri, OnDeepLinkActivated);
117119
#endif
@@ -161,7 +163,7 @@ private async UniTask<bool> Relogin()
161163
return false;
162164
}
163165

164-
public async UniTask<bool> ConnectImx(bool useCachedSession = false)
166+
public async UniTask<bool> ConnectImx(bool useCachedSession = false, DirectLoginMethod directLoginMethod = DirectLoginMethod.None)
165167
{
166168
if (useCachedSession)
167169
{
@@ -187,6 +189,7 @@ public async UniTask<bool> ConnectImx(bool useCachedSession = false)
187189
UniTaskCompletionSource<bool> task = new UniTaskCompletionSource<bool>();
188190
_pkceCompletionSource = task;
189191
_pkceLoginOnly = false;
192+
_directLoginMethod = directLoginMethod;
190193

191194
#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN)
192195
WindowsDeepLink.Initialise(_redirectUri, OnDeepLinkActivated);
@@ -272,7 +275,8 @@ private async UniTask LaunchAuthUrl()
272275
{
273276
try
274277
{
275-
string callResponse = await _communicationsManager.Call(PassportFunction.GET_PKCE_AUTH_URL);
278+
var request = new GetPKCEAuthUrlRequest(!_pkceLoginOnly, _directLoginMethod);
279+
string callResponse = await _communicationsManager.Call(PassportFunction.GET_PKCE_AUTH_URL, JsonUtility.ToJson(request));
276280
StringResponse response = callResponse.OptDeserializeObject<StringResponse>();
277281

278282
if (response != null && response.success == true && response.result != null)

src/Packages/Passport/Runtime/Scripts/Public/Passport.cs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -288,23 +288,25 @@ public void SetCallTimeout(int ms)
288288
/// Logs into Passport using Authorisation Code Flow with Proof Key for Code Exchange (PKCE).
289289
/// This opens the user's default browser on desktop or an in-app browser on mobile.
290290
/// <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>
291+
/// <param name="directLoginMethod">Optional direct login method to use (google, apple, facebook). If None, the user will see the standard login page.</param>
291292
/// </summary>
292293
/// <returns>
293294
/// Returns true if login is successful, otherwise false.
294295
/// </returns>
295-
public async UniTask<bool> Login(bool useCachedSession = false)
296+
public async UniTask<bool> Login(bool useCachedSession = false, DirectLoginMethod directLoginMethod = DirectLoginMethod.None)
296297
{
297-
return await GetPassportImpl().Login(useCachedSession);
298+
return await GetPassportImpl().Login(useCachedSession, directLoginMethod);
298299
}
299300

300301
/// <summary>
301302
/// Logs the user into Passport using Authorisation Code Flow with Proof Key for Code Exchange (PKCE) and sets up the Immutable X provider.
302303
/// This opens the user's default browser on desktop or an in-app browser on mobile.
303304
/// <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>
305+
/// <param name="directLoginMethod">Optional direct login method to use (google, apple, facebook). If None, the user will see the standard login page.</param>
304306
/// </summary>
305-
public async UniTask<bool> ConnectImx(bool useCachedSession = false)
307+
public async UniTask<bool> ConnectImx(bool useCachedSession = false, DirectLoginMethod directLoginMethod = DirectLoginMethod.None)
306308
{
307-
return await GetPassportImpl().ConnectImx(useCachedSession);
309+
return await GetPassportImpl().ConnectImx(useCachedSession, directLoginMethod);
308310
}
309311

310312
/// <summary>

0 commit comments

Comments
 (0)