Skip to content

[ID-3859] feat: Passport prefab #539

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 33 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
e556262
feat(passport): add passport manager prefab
CodeSchwert Aug 5, 2025
8b3fc3b
feat(passport): add prefab to package samples
CodeSchwert Aug 5, 2025
20df644
feat(passport): add ui controller example
CodeSchwert Aug 5, 2025
b43ecd7
docs(passport): add passport manager samples readme
CodeSchwert Aug 5, 2025
d8d02be
docs(passport): lint fix prefab samples readme
CodeSchwert Aug 5, 2025
a817e63
fix(passport): fix deeplinking log path
CodeSchwert Aug 5, 2025
a49ace5
feat: add prefab with ui elements baked in
CodeSchwert Aug 8, 2025
111be79
update README
CodeSchwert Aug 11, 2025
65cf736
Merge branch 'main' into feat/passport-prefab
CodeSchwert Aug 11, 2025
5ff7369
feat: add marketing consent support to sdk and prefab
CodeSchwert Aug 12, 2025
8e44b05
chore: lint trailing white space
CodeSchwert Aug 12, 2025
2d241c8
chore: remove comment
CodeSchwert Aug 12, 2025
84ae7a6
docs: update tooltips and quick start
CodeSchwert Aug 12, 2025
fa31da3
docs: default login method setting
CodeSchwert Aug 12, 2025
2900b39
chore: lint fix
CodeSchwert Aug 12, 2025
a9c6fce
feat(tests): implement reliable CI authentication automation
CodeSchwert Aug 18, 2025
5e5b616
fix(ci): prevent parallel UI tests from competing for same email inbox
CodeSchwert Aug 18, 2025
8c13d0f
refactor: decouple UI components from core SDK
CodeSchwert Aug 18, 2025
32cd757
ci: prevent unnecessary test cancellations in UI workflow
CodeSchwert Aug 18, 2025
fe27997
fix: implement smart login with state-aware authentication flow
CodeSchwert Aug 18, 2025
9aa31f7
ci: skipping imx transfer tests
CodeSchwert Aug 18, 2025
19c9330
ci: skip imx tests for mac
CodeSchwert Aug 18, 2025
c3fac60
ci: debug login button
CodeSchwert Aug 18, 2025
90d3de0
test: force clean Unity state on test startup
CodeSchwert Aug 18, 2025
4caf298
Merge branch 'main' into feat/passport-prefab
CodeSchwert Aug 19, 2025
93bdf88
chore: post merge tidy up
CodeSchwert Aug 19, 2025
55227f3
chore: cleanup deps
CodeSchwert Aug 19, 2025
bc55364
chore: revert unitask version
CodeSchwert Aug 20, 2025
16a30f4
chore: revert unitask version
CodeSchwert Aug 20, 2025
13c9390
docs: american english typos
CodeSchwert Aug 20, 2025
c005c8c
feat: social login button prefabs
nattb8 Aug 20, 2025
2840b94
feat: passport login ui prefab
CodeSchwert Aug 20, 2025
178fcb9
chore: move asset to correct folder
CodeSchwert Aug 21, 2025
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
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,15 @@ private static void CreateCommandScript(string protocolName)
" powershell -NoProfile -ExecutionPolicy Bypass -Command ^",
" \"$ErrorActionPreference = 'Continue';\" ^",
" \"$wshell = New-Object -ComObject wscript.shell;\" ^",
" \"Add-Content -Path \\\"{logPath}\\\" -Value ('[' + (Get-Date) + '] Attempting to activate process ID: ' + %%A);\" ^",
$" \"Add-Content -Path \\\"{logPath}\\\" -Value ('[' + (Get-Date) + '] Attempting to activate process ID: ' + %%A);\" ^",
" \"Start-Sleep -Milliseconds 100;\" ^",
" \"$result = $wshell.AppActivate(%%A);\" ^",
" \"Add-Content -Path \\\"{logPath}\\\" -Value ('[' + (Get-Date) + '] AppActivate result: ' + $result);\" ^",
" \"if (-not $result) { Add-Content -Path \\\"{logPath}\\\" -Value ('[' + (Get-Date) + '] Failed to activate window') }\" ^",
$" \"Add-Content -Path \\\"{logPath}\\\" -Value ('[' + (Get-Date) + '] AppActivate result: ' + $result);\" ^",
$" \"if (-not $result) {{ Add-Content -Path \\\"{logPath}\\\" -Value ('[' + (Get-Date) + '] Failed to activate window') }}\" ^",
" >nul 2>&1",
" if errorlevel 1 echo [%date% %time%] PowerShell error: %errorlevel% >> \"%LOG_PATH%\"",
" echo [%date% %time%] Unity activated, self-deleting >> \"%LOG_PATH%\"",
$" del \"%~f0\" >nul 2>&1",
" endlocal",
" exit /b 0",
" )",
Expand All @@ -159,7 +161,11 @@ private static void CreateCommandScript(string protocolName)
"",
// Start new Unity instance if none found
$"echo [%date% %time%] Starting new Unity instance >> \"%LOG_PATH%\"",
$"start \"\" \"{unityExe}\" -projectPath \"%PROJECT_PATH%\" >nul 2>&1"
$"start \"\" \"{unityExe}\" -projectPath \"%PROJECT_PATH%\" >nul 2>&1",
"",
// Self-delete the batch file when done
"echo [%date% %time%] Script completed, self-deleting >> \"%LOG_PATH%\"",
$"del \"%~f0\" >nul 2>&1"
};

File.WriteAllLines(cmdPath, scriptLines);
Expand Down Expand Up @@ -395,18 +401,10 @@ private void HandleDeeplink()
}

// Clean up command script
// Note: Batch file will self-delete, no need to delete here
// This prevents race condition where Unity deletes the file
// while Windows is still trying to execute it
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);
Expand All @@ -415,4 +413,3 @@ private void HandleDeeplink()
}
}
#endif

Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ namespace Immutable.Passport.Model
[Serializable]
public enum DirectLoginMethod
{
None,
Email,
Google,
Apple,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,24 +19,32 @@ public class DirectLoginOptions
/// </summary>
public string email;

/// <summary>
/// Marketing consent status (optional).
/// </summary>
public MarketingConsentStatus? marketingConsentStatus;

/// <summary>
/// Default constructor.
/// </summary>
public DirectLoginOptions()
{
directLoginMethod = DirectLoginMethod.Email;
email = null;
marketingConsentStatus = 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)
/// <param name="marketingConsentStatus">The marketing consent status (optional)</param>
public DirectLoginOptions(DirectLoginMethod loginMethod, string emailAddress = null, MarketingConsentStatus? marketingConsentStatus = null)
{
directLoginMethod = loginMethod;
email = emailAddress;
this.marketingConsentStatus = marketingConsentStatus;
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using System;

namespace Immutable.Passport.Model
{
/// <summary>
/// Enum representing marketing consent status.
/// </summary>
[Serializable]
public enum MarketingConsentStatus
{
OptedIn,
Unsubscribed
}

/// <summary>
/// Extension methods for MarketingConsentStatus enum.
/// </summary>
public static class MarketingConsentStatusExtensions
{
/// <summary>
/// Converts the enum value to the string format expected by the game bridge.
/// </summary>
/// <param name="status">The marketing consent status</param>
/// <returns>The corresponding string value</returns>
public static string ToApiString(this MarketingConsentStatus status)
{
return status switch
{
MarketingConsentStatus.OptedIn => "opted_in",
MarketingConsentStatus.Unsubscribed => "unsubscribed",
_ => throw new ArgumentOutOfRangeException(nameof(status), status, "Unknown MarketingConsentStatus value")
};
}
}
}

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

13 changes: 12 additions & 1 deletion src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -287,11 +287,22 @@ private async UniTask LaunchAuthUrl()
requestJson += $",\"email\":\"{_directLoginOptions.email}\"";
}

if (_directLoginOptions.marketingConsentStatus != null)
{
var consentValue = _directLoginOptions.marketingConsentStatus.Value.ToApiString();
requestJson += $",\"marketingConsentStatus\":\"{consentValue}\"";
}

requestJson += "}";
}
else
{
PassportLogger.Debug($"{TAG} No direct login options provided (standard auth flow)");
}

requestJson += "}";

PassportLogger.Debug($"{TAG} Sending auth URL request: {requestJson}");
var callResponse = await _communicationsManager.Call(PassportFunction.GET_PKCE_AUTH_URL, requestJson);
var response = callResponse.OptDeserializeObject<StringResponse>();

Expand Down Expand Up @@ -774,7 +785,7 @@ public interface PKCECallback
{

/// <summary>
/// Called when the Android Chrome Custom Tabs is hidden.
/// Called when the Android Chrome Custom Tabs is hidden.
/// Note that you won't be able to tell whether it was closed by the user or the SDK.
/// <param name="completing">True if the user has entered everything required (e.g. email address),
/// Chrome Custom Tabs have closed, and the SDK is trying to complete the PKCE flow.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
{
"name": "Immutable.Passport.Samples",
"rootNamespace": "Immutable.Passport",
"references": [
"Immutable.Passport.Runtime.Public",
"Immutable.Passport.Runtime.Private",
"Immutable.Passport.Core.Logging",
"Immutable.Browser.Core",
"UniTask",
"Unity.Modules.UI",
"Unity.TextMeshPro"
],
"includePlatforms": [
"Android",
"Editor",
"iOS",
"macOSStandalone",
"WebGL",
"WindowsStandalone64"
],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": false,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}
Loading
Loading