From ab83c0d752d1611baaa45a23fc56122903e786ac Mon Sep 17 00:00:00 2001 From: Natalie Bunduwongse Date: Thu, 12 Jun 2025 16:26:32 +1200 Subject: [PATCH 1/8] feat: remove device code auth --- .../Scenes/Passport/AuthenticatedScene.unity | 4 +- ...tAuthMethod.unity => Initialisation.unity} | 784 +-------------- ...d.unity.meta => Initialisation.unity.meta} | 0 .../Passport/UnauthenticatedScene.unity | 341 +------ .../Passport/AuthenticatedSceneManager.cs | 2 +- .../ClearStorageAndCacheScript.cs | 2 +- .../Passport/GetUserInfo/GetUserInfoScript.cs | 2 +- .../Passport/ImxConnect/ImxConnectScript.cs | 8 +- .../ImxGetAddress/ImxGetAddressScript.cs | 4 +- .../ImxIsRegisteredOffchainScript.cs | 4 +- .../ImxNftTransfer/ImxNftTransferScript.cs | 2 +- .../Passport/ImxRegister/ImxRegisterScript.cs | 2 +- .../Scripts/Passport/Login/LoginScript.cs | 30 +- .../Scripts/Passport/Logout/LogoutScript.cs | 11 +- .../Other/AuthenticatedSceneNavigation.cs | 2 +- .../SetCallTimeout/SetCallTimeoutScript.cs | 2 +- .../PassportInitialisationScript.cs | 64 +- .../Passport/Reconnect/ReconnectScript.cs | 3 +- .../Scripts/Passport/Relogin/ReloginScript.cs | 2 +- .../Scripts/Passport/SampleAppManager.cs | 7 +- .../Passport/UnauthenticatedSceneManager.cs | 12 +- .../ZkEvm/ZkEvmConnect/ZkEvmConnectScript.cs | 8 +- .../ZkEvmGetBalance/ZkEvmGetBalanceScript.cs | 2 +- .../ZkEvmGetTransactionReceiptScript.cs | 2 +- .../ZkEvmSendTransactionScript.cs | 9 +- .../ZkEvmSignTypedDataScript.cs | 2 +- .../ProjectSettings/EditorBuildSettings.asset | 2 +- .../Private/Core/Model/BrowserResponse.cs | 47 +- .../Private/Event/PassportAuthEvent.cs | 59 -- .../Scripts/Private/Helpers/JsonHelpers.cs | 2 +- .../Model/Request/ConfirmCodeRequest.cs | 13 - .../Model/Request/ConfirmCodeRequest.cs.meta | 11 - .../Private/Model/Request/InitRequest.cs | 9 - .../Model/Response/DeviceConnectResponse.cs | 12 - .../Response/DeviceConnectResponse.cs.meta | 11 - .../Runtime/Scripts/Private/PassportImpl.cs | 528 ++++------ .../Runtime/Scripts/Public/Passport.cs | 168 ++-- .../Tests/Runtime/Scripts/PassportTests.cs | 901 +----------------- 38 files changed, 382 insertions(+), 2692 deletions(-) rename sample/Assets/Scenes/Passport/{SelectAuthMethod.unity => Initialisation.unity} (68%) rename sample/Assets/Scenes/Passport/{SelectAuthMethod.unity.meta => Initialisation.unity.meta} (100%) delete mode 100644 src/Packages/Passport/Runtime/Scripts/Private/Model/Request/ConfirmCodeRequest.cs delete mode 100644 src/Packages/Passport/Runtime/Scripts/Private/Model/Request/ConfirmCodeRequest.cs.meta delete mode 100644 src/Packages/Passport/Runtime/Scripts/Private/Model/Response/DeviceConnectResponse.cs delete mode 100644 src/Packages/Passport/Runtime/Scripts/Private/Model/Response/DeviceConnectResponse.cs.meta diff --git a/sample/Assets/Scenes/Passport/AuthenticatedScene.unity b/sample/Assets/Scenes/Passport/AuthenticatedScene.unity index 8f0560dd..35e0666e 100644 --- a/sample/Assets/Scenes/Passport/AuthenticatedScene.unity +++ b/sample/Assets/Scenes/Passport/AuthenticatedScene.unity @@ -1218,7 +1218,7 @@ MonoBehaviour: m_TargetGraphic: {fileID: 66309839} m_HandleRect: {fileID: 66309838} m_Direction: 0 - m_Value: 1 + m_Value: 0 m_Size: 1 m_NumberOfSteps: 0 m_OnValueChanged: @@ -3092,7 +3092,7 @@ MonoBehaviour: m_HandleRect: {fileID: 1741513413} m_Direction: 2 m_Value: 1 - m_Size: 0.99999994 + m_Size: 1 m_NumberOfSteps: 0 m_OnValueChanged: m_PersistentCalls: diff --git a/sample/Assets/Scenes/Passport/SelectAuthMethod.unity b/sample/Assets/Scenes/Passport/Initialisation.unity similarity index 68% rename from sample/Assets/Scenes/Passport/SelectAuthMethod.unity rename to sample/Assets/Scenes/Passport/Initialisation.unity index 17596d41..154b4ed7 100644 --- a/sample/Assets/Scenes/Passport/SelectAuthMethod.unity +++ b/sample/Assets/Scenes/Passport/Initialisation.unity @@ -206,8 +206,8 @@ MonoBehaviour: m_TargetGraphic: {fileID: 416242725} m_HandleRect: {fileID: 416242724} m_Direction: 0 - m_Value: 1 - m_Size: 0.99999994 + m_Value: 0 + m_Size: 1 m_NumberOfSteps: 0 m_OnValueChanged: m_PersistentCalls: @@ -549,86 +549,6 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 416242723} m_CullTransparentMesh: 1 ---- !u!1 &458414018 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 458414019} - - component: {fileID: 458414021} - - component: {fileID: 458414020} - m_Layer: 5 - m_Name: Text (Legacy) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &458414019 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 458414018} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1744191471} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &458414020 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 458414018} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 24 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 2 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: PKCE (Recommended) ---- !u!222 &458414021 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 458414018} - m_CullTransparentMesh: 1 --- !u!1 &519420028 GameObject: m_ObjectHideFlags: 0 @@ -713,161 +633,6 @@ Transform: m_Father: {fileID: 0} m_RootOrder: 0 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} ---- !u!1 &717484782 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 717484783} - - component: {fileID: 717484786} - - component: {fileID: 717484785} - - component: {fileID: 717484784} - - component: {fileID: 717484787} - m_Layer: 5 - m_Name: DeviceCodeAuth - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &717484783 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 717484782} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 2131905290} - m_Father: {fileID: 1915378375} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &717484784 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 717484782} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_WrapAround: 0 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_SelectedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_SelectedTrigger: Selected - m_DisabledTrigger: Disabled - m_Interactable: 1 - m_TargetGraphic: {fileID: 717484785} - m_OnClick: - m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 1314882729} - m_TargetAssemblyTypeName: PassportInitialisationScript, Assembly-CSharp - m_MethodName: UseDeviceCodeAuth - m_Mode: 1 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 ---- !u!114 &717484785 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 717484782} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 3} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 ---- !u!222 &717484786 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 717484782} - m_CullTransparentMesh: 1 ---- !u!114 &717484787 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 717484782} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreLayout: 0 - m_MinWidth: -1 - m_MinHeight: -1 - m_PreferredWidth: 260 - m_PreferredHeight: 60 - m_FlexibleWidth: -1 - m_FlexibleHeight: -1 - m_LayoutPriority: 1 --- !u!1 &854433808 GameObject: m_ObjectHideFlags: 0 @@ -1129,8 +894,6 @@ RectTransform: m_Children: - {fileID: 854433809} - {fileID: 1661390144} - - {fileID: 1688502348} - - {fileID: 1915378375} - {fileID: 1311161409} - {fileID: 1508764521} m_Father: {fileID: 1850628784} @@ -1209,7 +972,7 @@ RectTransform: m_ConstrainProportionsScale: 0 m_Children: [] m_Father: {fileID: 1238552242} - m_RootOrder: 4 + m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1267,8 +1030,6 @@ MonoBehaviour: m_EditorClassIdentifier: TopPadding: {fileID: 0} Output: {fileID: 1690937182} - UseDeviceCodeAuthButton: {fileID: 717484784} - UsePKCEButton: {fileID: 1744191472} --- !u!4 &1314882730 Transform: m_ObjectHideFlags: 0 @@ -1368,7 +1129,7 @@ MonoBehaviour: m_HandleRect: {fileID: 167431871} m_Direction: 2 m_Value: 1 - m_Size: 0.99999994 + m_Size: 1 m_NumberOfSteps: 0 m_OnValueChanged: m_PersistentCalls: @@ -1480,7 +1241,7 @@ RectTransform: m_Children: - {fileID: 172384059} m_Father: {fileID: 1238552242} - m_RootOrder: 5 + m_RootOrder: 3 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} @@ -1533,86 +1294,6 @@ MonoBehaviour: m_ChildScaleWidth: 0 m_ChildScaleHeight: 0 m_ReverseArrangement: 0 ---- !u!1 &1523853785 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1523853786} - - component: {fileID: 1523853788} - - component: {fileID: 1523853787} - m_Layer: 5 - m_Name: SelectLoginMethod - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1523853786 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1523853785} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1915378375} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1523853787 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1523853785} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 3} - m_FontSize: 24 - m_FontStyle: 1 - m_BestFit: 0 - m_MinSize: 0 - m_MaxSize: 224 - m_Alignment: 3 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Login method ---- !u!222 &1523853788 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1523853785} - m_CullTransparentMesh: 1 --- !u!1 &1557497261 GameObject: m_ObjectHideFlags: 0 @@ -1717,8 +1398,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 841.85657, y: 0} - m_SizeDelta: {x: 1643.7131, y: 0} + m_AnchoredPosition: {x: 1108.9248, y: 0} + m_SizeDelta: {x: 2177.8496, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &1661390145 MonoBehaviour: @@ -1753,7 +1434,7 @@ MonoBehaviour: m_HorizontalOverflow: 0 m_VerticalOverflow: 0 m_LineSpacing: 1 - m_Text: Authentication methods + m_Text: Passport initialisation --- !u!222 &1661390146 CanvasRenderer: m_ObjectHideFlags: 0 @@ -1776,7 +1457,7 @@ MonoBehaviour: m_EditorClassIdentifier: m_HorizontalFit: 0 m_VerticalFit: 2 ---- !u!1 &1688502347 +--- !u!1 &1690937179 GameObject: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} @@ -1784,136 +1465,24 @@ GameObject: m_PrefabAsset: {fileID: 0} serializedVersion: 6 m_Component: - - component: {fileID: 1688502348} - - component: {fileID: 1688502351} - - component: {fileID: 1688502350} - - component: {fileID: 1688502349} + - component: {fileID: 1690937180} + - component: {fileID: 1690937181} + - component: {fileID: 1690937182} m_Layer: 5 - m_Name: Description + m_Name: Output m_TagString: Untagged m_Icon: {fileID: 0} m_NavMeshLayer: 0 m_StaticEditorFlags: 0 m_IsActive: 1 ---- !u!224 &1688502348 +--- !u!224 &1690937180 RectTransform: m_ObjectHideFlags: 0 m_CorrespondingSourceObject: {fileID: 0} m_PrefabInstance: {fileID: 0} m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1688502347} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 1238552242} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 841.85657, y: 0} - m_SizeDelta: {x: 1643.7131, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1688502349 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1688502347} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 3245ec927659c4140ac4f8d17403cc18, type: 3} - m_Name: - m_EditorClassIdentifier: - m_HorizontalFit: 0 - m_VerticalFit: 2 ---- !u!114 &1688502350 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1688502347} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 24 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 2 - m_MaxSize: 40 - m_Alignment: 3 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: 'There are two methods to authenticate and authorise players into Passport: - - - 1. - Authorisation Code Flow with Proof Key for Code Exchange (PKCE): This method provides - a seamless and secure authentication experience by opening a pop-up window on - desktop or an in-app browser on mobile devices. Players are automatically redirected - back to the game once authenticated, eliminating manual switching. - - - 2. Device - Code Authorisation: This method - opens the player''s default browser and guides them through the authentication - flow. - - - Recommendation: Whenever possible, use the PKCE flow as it is the - most secure and seamless method for authentication.' ---- !u!222 &1688502351 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1688502347} - m_CullTransparentMesh: 1 ---- !u!1 &1690937179 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1690937180} - - component: {fileID: 1690937181} - - component: {fileID: 1690937182} - m_Layer: 5 - m_Name: Output - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1690937180 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1690937179} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} + m_GameObject: {fileID: 1690937179} + m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} m_LocalPosition: {x: 0, y: 0, z: 0} m_LocalScale: {x: 1, y: 1, z: 1} m_ConstrainProportionsScale: 0 @@ -1968,161 +1537,6 @@ MonoBehaviour: m_VerticalOverflow: 0 m_LineSpacing: 1 m_Text: ---- !u!1 &1744191470 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1744191471} - - component: {fileID: 1744191474} - - component: {fileID: 1744191473} - - component: {fileID: 1744191472} - - component: {fileID: 1744191475} - m_Layer: 5 - m_Name: PKCE - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1744191471 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1744191470} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 458414019} - m_Father: {fileID: 1915378375} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1744191472 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1744191470} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 4e29b1a8efbd4b44bb3f3716e73f07ff, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_WrapAround: 0 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_SelectedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_SelectedTrigger: Selected - m_DisabledTrigger: Disabled - m_Interactable: 1 - m_TargetGraphic: {fileID: 1744191473} - m_OnClick: - m_PersistentCalls: - m_Calls: - - m_Target: {fileID: 1314882729} - m_TargetAssemblyTypeName: PassportInitialisationScript, Assembly-CSharp - m_MethodName: UsePKCE - m_Mode: 1 - m_Arguments: - m_ObjectArgument: {fileID: 0} - m_ObjectArgumentAssemblyTypeName: UnityEngine.Object, UnityEngine - m_IntArgument: 0 - m_FloatArgument: 0 - m_StringArgument: - m_BoolArgument: 0 - m_CallState: 2 ---- !u!114 &1744191473 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1744191470} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 10905, guid: 0000000000000000f000000000000000, type: 3} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 ---- !u!222 &1744191474 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1744191470} - m_CullTransparentMesh: 1 ---- !u!114 &1744191475 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1744191470} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreLayout: 0 - m_MinWidth: -1 - m_MinHeight: -1 - m_PreferredWidth: 260 - m_PreferredHeight: 60 - m_FlexibleWidth: -1 - m_FlexibleHeight: -1 - m_LayoutPriority: 1 --- !u!1 &1850628783 GameObject: m_ObjectHideFlags: 0 @@ -2279,169 +1693,3 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 1850628783} m_CullTransparentMesh: 1 ---- !u!1 &1915378374 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 1915378375} - - component: {fileID: 1915378376} - - component: {fileID: 1915378377} - m_Layer: 5 - m_Name: Method - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &1915378375 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1915378374} - m_LocalRotation: {x: 0, y: 0, z: 0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 1523853786} - - {fileID: 1744191471} - - {fileID: 717484783} - m_Father: {fileID: 1238552242} - m_RootOrder: 3 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &1915378376 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1915378374} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreLayout: 0 - m_MinWidth: -1 - m_MinHeight: -1 - m_PreferredWidth: -1 - m_PreferredHeight: 60 - m_FlexibleWidth: -1 - m_FlexibleHeight: -1 - m_LayoutPriority: 1 ---- !u!114 &1915378377 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 1915378374} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 558b109da67a27b4686138b955f3a7e8, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Padding: - m_Left: 0 - m_Right: 0 - m_Top: 0 - m_Bottom: 0 - m_ChildAlignment: 3 - SpacingX: 16 - SpacingY: 16 - ExpandHorizontalSpacing: 0 - ChildForceExpandWidth: 0 - ChildForceExpandHeight: 0 - invertOrder: 0 - m_StartAxis: 0 ---- !u!1 &2131905289 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 2131905290} - - component: {fileID: 2131905292} - - component: {fileID: 2131905291} - m_Layer: 5 - m_Name: Text (Legacy) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &2131905290 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2131905289} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 717484783} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: 0} - m_SizeDelta: {x: 0, y: 0} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &2131905291 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2131905289} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 24 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 2 - m_MaxSize: 40 - m_Alignment: 4 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Device Code Auth ---- !u!222 &2131905292 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2131905289} - m_CullTransparentMesh: 1 diff --git a/sample/Assets/Scenes/Passport/SelectAuthMethod.unity.meta b/sample/Assets/Scenes/Passport/Initialisation.unity.meta similarity index 100% rename from sample/Assets/Scenes/Passport/SelectAuthMethod.unity.meta rename to sample/Assets/Scenes/Passport/Initialisation.unity.meta diff --git a/sample/Assets/Scenes/Passport/UnauthenticatedScene.unity b/sample/Assets/Scenes/Passport/UnauthenticatedScene.unity index 53c08477..1350ad71 100644 --- a/sample/Assets/Scenes/Passport/UnauthenticatedScene.unity +++ b/sample/Assets/Scenes/Passport/UnauthenticatedScene.unity @@ -203,254 +203,6 @@ CanvasRenderer: m_PrefabAsset: {fileID: 0} m_GameObject: {fileID: 415205} m_CullTransparentMesh: 1 ---- !u!1 &160623835 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 160623836} - - component: {fileID: 160623838} - - component: {fileID: 160623837} - m_Layer: 5 - m_Name: Text (Legacy) - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &160623836 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 160623835} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 233062548} - m_RootOrder: 1 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: -0.5} - m_SizeDelta: {x: -20, y: -13} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &160623837 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 160623835} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 24 - m_FontStyle: 0 - m_BestFit: 0 - m_MinSize: 2 - m_MaxSize: 40 - m_Alignment: 3 - m_AlignByGeometry: 0 - m_RichText: 0 - m_HorizontalOverflow: 1 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: ---- !u!222 &160623838 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 160623835} - m_CullTransparentMesh: 1 ---- !u!1 &233062547 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 233062548} - - component: {fileID: 233062551} - - component: {fileID: 233062550} - - component: {fileID: 233062549} - - component: {fileID: 233062552} - m_Layer: 5 - m_Name: DeviceCodeTimeoutMs - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &233062548 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 233062547} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: - - {fileID: 2127039960} - - {fileID: 160623836} - m_Father: {fileID: 1349788404} - m_RootOrder: 2 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 1} - m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 777, y: -30} - m_SizeDelta: {x: 450, y: 60} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &233062549 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 233062547} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: d199490a83bb2b844b9695cbf13b01ef, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Navigation: - m_Mode: 3 - m_WrapAround: 0 - m_SelectOnUp: {fileID: 0} - m_SelectOnDown: {fileID: 0} - m_SelectOnLeft: {fileID: 0} - m_SelectOnRight: {fileID: 0} - m_Transition: 1 - m_Colors: - m_NormalColor: {r: 1, g: 1, b: 1, a: 1} - m_HighlightedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_PressedColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 1} - m_SelectedColor: {r: 0.9607843, g: 0.9607843, b: 0.9607843, a: 1} - m_DisabledColor: {r: 0.78431374, g: 0.78431374, b: 0.78431374, a: 0.5019608} - m_ColorMultiplier: 1 - m_FadeDuration: 0.1 - m_SpriteState: - m_HighlightedSprite: {fileID: 0} - m_PressedSprite: {fileID: 0} - m_SelectedSprite: {fileID: 0} - m_DisabledSprite: {fileID: 0} - m_AnimationTriggers: - m_NormalTrigger: Normal - m_HighlightedTrigger: Highlighted - m_PressedTrigger: Pressed - m_SelectedTrigger: Selected - m_DisabledTrigger: Disabled - m_Interactable: 1 - m_TargetGraphic: {fileID: 233062550} - m_TextComponent: {fileID: 160623837} - m_Placeholder: {fileID: 2127039961} - m_ContentType: 0 - m_InputType: 0 - m_AsteriskChar: 42 - m_KeyboardType: 0 - m_LineType: 0 - m_HideMobileInput: 0 - m_CharacterValidation: 0 - m_CharacterLimit: 0 - m_OnSubmit: - m_PersistentCalls: - m_Calls: [] - m_OnDidEndEdit: - m_PersistentCalls: - m_Calls: [] - m_OnValueChanged: - m_PersistentCalls: - m_Calls: [] - m_CaretColor: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 1} - m_CustomCaretColor: 0 - m_SelectionColor: {r: 0.65882355, g: 0.80784315, b: 1, a: 0.7529412} - m_Text: - m_CaretBlinkRate: 0.85 - m_CaretWidth: 1 - m_ReadOnly: 0 - m_ShouldActivateOnSelect: 1 ---- !u!114 &233062550 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 233062547} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: fe87c0e1cc204ed48ad3b37840f39efc, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 1, g: 1, b: 1, a: 1} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_Sprite: {fileID: 10911, guid: 0000000000000000f000000000000000, type: 0} - m_Type: 1 - m_PreserveAspect: 0 - m_FillCenter: 1 - m_FillMethod: 4 - m_FillAmount: 1 - m_FillClockwise: 1 - m_FillOrigin: 0 - m_UseSpriteMesh: 0 - m_PixelsPerUnitMultiplier: 1 ---- !u!222 &233062551 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 233062547} - m_CullTransparentMesh: 1 ---- !u!114 &233062552 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 233062547} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 306cc8c2b49d7114eaa3623786fc2126, type: 3} - m_Name: - m_EditorClassIdentifier: - m_IgnoreLayout: 0 - m_MinWidth: -1 - m_MinHeight: -1 - m_PreferredWidth: 450 - m_PreferredHeight: 60 - m_FlexibleWidth: -1 - m_FlexibleHeight: -1 - m_LayoutPriority: 1 --- !u!1 &270318904 GameObject: m_ObjectHideFlags: 0 @@ -958,7 +710,7 @@ MonoBehaviour: m_TargetGraphic: {fileID: 1541372192} m_HandleRect: {fileID: 1541372191} m_Direction: 0 - m_Value: 1 + m_Value: 0 m_Size: 1 m_NumberOfSteps: 0 m_OnValueChanged: @@ -2383,7 +2135,7 @@ MonoBehaviour: m_HandleRect: {fileID: 1495172581} m_Direction: 2 m_Value: 1 - m_Size: 0.99999994 + m_Size: 1 m_NumberOfSteps: 0 m_OnValueChanged: m_PersistentCalls: @@ -2589,7 +2341,7 @@ MonoBehaviour: m_EditorClassIdentifier: LoginButtons: {fileID: 1349788403} ReloginButtons: {fileID: 756533207} - DeviceCodeTimeoutMs: {fileID: 233062549} + DeviceCodeTimeoutMs: {fileID: 0} --- !u!1 &1173574366 GameObject: m_ObjectHideFlags: 0 @@ -2702,14 +2454,13 @@ RectTransform: m_Children: - {fileID: 892906553} - {fileID: 291915219} - - {fileID: 233062548} m_Father: {fileID: 997036539} m_RootOrder: 2 m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 1} m_AnchorMax: {x: 0, y: 1} - m_AnchoredPosition: {x: 852.55914, y: -130} - m_SizeDelta: {x: 1665.1183, y: 60} + m_AnchoredPosition: {x: 1108.9248, y: -130} + m_SizeDelta: {x: 2177.8496, y: 60} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &1349788406 MonoBehaviour: @@ -3514,7 +3265,7 @@ MonoBehaviour: m_Name: m_EditorClassIdentifier: Output: {fileID: 1615533291} - DeviceCodeTimeoutMs: {fileID: 233062549} + DeviceCodeTimeoutMs: {fileID: 0} --- !u!4 &1883395345 Transform: m_ObjectHideFlags: 0 @@ -3567,83 +3318,3 @@ RectTransform: m_AnchoredPosition: {x: 0, y: 0} m_SizeDelta: {x: -20, y: -20} m_Pivot: {x: 0.5, y: 0.5} ---- !u!1 &2127039959 -GameObject: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - serializedVersion: 6 - m_Component: - - component: {fileID: 2127039960} - - component: {fileID: 2127039962} - - component: {fileID: 2127039961} - m_Layer: 5 - m_Name: Placeholder - m_TagString: Untagged - m_Icon: {fileID: 0} - m_NavMeshLayer: 0 - m_StaticEditorFlags: 0 - m_IsActive: 1 ---- !u!224 &2127039960 -RectTransform: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2127039959} - m_LocalRotation: {x: -0, y: -0, z: -0, w: 1} - m_LocalPosition: {x: 0, y: 0, z: 0} - m_LocalScale: {x: 1, y: 1, z: 1} - m_ConstrainProportionsScale: 0 - m_Children: [] - m_Father: {fileID: 233062548} - m_RootOrder: 0 - m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} - m_AnchorMin: {x: 0, y: 0} - m_AnchorMax: {x: 1, y: 1} - m_AnchoredPosition: {x: 0, y: -0.5} - m_SizeDelta: {x: -20, y: -13} - m_Pivot: {x: 0.5, y: 0.5} ---- !u!114 &2127039961 -MonoBehaviour: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2127039959} - m_Enabled: 1 - m_EditorHideFlags: 0 - m_Script: {fileID: 11500000, guid: 5f7201a12d95ffc409449d95f23cf332, type: 3} - m_Name: - m_EditorClassIdentifier: - m_Material: {fileID: 0} - m_Color: {r: 0.19607843, g: 0.19607843, b: 0.19607843, a: 0.5} - m_RaycastTarget: 1 - m_RaycastPadding: {x: 0, y: 0, z: 0, w: 0} - m_Maskable: 1 - m_OnCullStateChanged: - m_PersistentCalls: - m_Calls: [] - m_FontData: - m_Font: {fileID: 10102, guid: 0000000000000000e000000000000000, type: 0} - m_FontSize: 24 - m_FontStyle: 2 - m_BestFit: 0 - m_MinSize: 2 - m_MaxSize: 40 - m_Alignment: 3 - m_AlignByGeometry: 0 - m_RichText: 1 - m_HorizontalOverflow: 0 - m_VerticalOverflow: 0 - m_LineSpacing: 1 - m_Text: Timeout in ms (leave blank for no timeout) ---- !u!222 &2127039962 -CanvasRenderer: - m_ObjectHideFlags: 0 - m_CorrespondingSourceObject: {fileID: 0} - m_PrefabInstance: {fileID: 0} - m_PrefabAsset: {fileID: 0} - m_GameObject: {fileID: 2127039959} - m_CullTransparentMesh: 1 diff --git a/sample/Assets/Scripts/Passport/AuthenticatedSceneManager.cs b/sample/Assets/Scripts/Passport/AuthenticatedSceneManager.cs index 0c2816a6..262029ff 100644 --- a/sample/Assets/Scripts/Passport/AuthenticatedSceneManager.cs +++ b/sample/Assets/Scripts/Passport/AuthenticatedSceneManager.cs @@ -62,4 +62,4 @@ public static void NavigateToUnauthenticatedScene() { UnityEngine.SceneManagement.SceneManager.LoadScene("UnauthenticatedScene"); } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/ClearStorageAndCache/ClearStorageAndCacheScript.cs b/sample/Assets/Scripts/Passport/ClearStorageAndCache/ClearStorageAndCacheScript.cs index 07b4d4bc..a3511998 100644 --- a/sample/Assets/Scripts/Passport/ClearStorageAndCache/ClearStorageAndCacheScript.cs +++ b/sample/Assets/Scripts/Passport/ClearStorageAndCache/ClearStorageAndCacheScript.cs @@ -38,4 +38,4 @@ private void ShowOutput(string message) } } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/GetUserInfo/GetUserInfoScript.cs b/sample/Assets/Scripts/Passport/GetUserInfo/GetUserInfoScript.cs index ba8ecc60..5fb95958 100644 --- a/sample/Assets/Scripts/Passport/GetUserInfo/GetUserInfoScript.cs +++ b/sample/Assets/Scripts/Passport/GetUserInfo/GetUserInfoScript.cs @@ -146,4 +146,4 @@ private void ShowOutput(string message) Output.text = message; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/ImxConnect/ImxConnectScript.cs b/sample/Assets/Scripts/Passport/ImxConnect/ImxConnectScript.cs index c768b218..4d3e9734 100644 --- a/sample/Assets/Scripts/Passport/ImxConnect/ImxConnectScript.cs +++ b/sample/Assets/Scripts/Passport/ImxConnect/ImxConnectScript.cs @@ -28,7 +28,7 @@ private async UniTaskVoid ConnectImxAsync() try { await Passport.Instance.ConnectImx(); - + SampleAppManager.IsConnectedToImx = true; ShowOutput("Connected to IMX"); // Show success early @@ -37,14 +37,14 @@ private async UniTaskVoid ConnectImxAsync() if (unauthSceneManager != null) { unauthSceneManager.OnImxConnected?.Invoke(); - return; + return; } var authSceneManager = FindObjectOfType(); if (authSceneManager != null) { authSceneManager.UpdateImxButtonStates(); - authSceneManager.OnImxConnected?.Invoke(); + authSceneManager.OnImxConnected?.Invoke(); return; } } @@ -61,4 +61,4 @@ private void ShowOutput(string message) Output.text = message; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/ImxGetAddress/ImxGetAddressScript.cs b/sample/Assets/Scripts/Passport/ImxGetAddress/ImxGetAddressScript.cs index 92b420ec..364d2374 100644 --- a/sample/Assets/Scripts/Passport/ImxGetAddress/ImxGetAddressScript.cs +++ b/sample/Assets/Scripts/Passport/ImxGetAddress/ImxGetAddressScript.cs @@ -31,7 +31,7 @@ public async void GetAddress() ShowOutput("Retrieving wallet address..."); try { - string address = await Passport.GetAddress(); + var address = await Passport.GetAddress(); ShowOutput(string.IsNullOrEmpty(address) ? "No address found" : address); } catch (PassportException e) @@ -51,4 +51,4 @@ private void ShowOutput(string message) Output.text = message; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/ImxIsRegisteredOffchain/ImxIsRegisteredOffchainScript.cs b/sample/Assets/Scripts/Passport/ImxIsRegisteredOffchain/ImxIsRegisteredOffchainScript.cs index cbb102ce..a7c31eb9 100644 --- a/sample/Assets/Scripts/Passport/ImxIsRegisteredOffchain/ImxIsRegisteredOffchainScript.cs +++ b/sample/Assets/Scripts/Passport/ImxIsRegisteredOffchain/ImxIsRegisteredOffchainScript.cs @@ -1,8 +1,6 @@ using UnityEngine; using UnityEngine.UI; using Cysharp.Threading.Tasks; -using Immutable.Passport; -using System; namespace Immutable.Passport.Sample.PassportFeatures { @@ -35,7 +33,7 @@ private async UniTaskVoid CheckIsRegisteredOffchainAsync() try { bool isRegistered = await SampleAppManager.PassportInstance.IsRegisteredOffchain(); - + if (isRegistered) { ShowOutput("Registered"); diff --git a/sample/Assets/Scripts/Passport/ImxNftTransfer/ImxNftTransferScript.cs b/sample/Assets/Scripts/Passport/ImxNftTransfer/ImxNftTransferScript.cs index 848a3f84..da4bb6c5 100644 --- a/sample/Assets/Scripts/Passport/ImxNftTransfer/ImxNftTransferScript.cs +++ b/sample/Assets/Scripts/Passport/ImxNftTransfer/ImxNftTransferScript.cs @@ -105,4 +105,4 @@ private void ShowOutput(string message) Output.text = message; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/ImxRegister/ImxRegisterScript.cs b/sample/Assets/Scripts/Passport/ImxRegister/ImxRegisterScript.cs index 8a224aca..c634a43d 100644 --- a/sample/Assets/Scripts/Passport/ImxRegister/ImxRegisterScript.cs +++ b/sample/Assets/Scripts/Passport/ImxRegister/ImxRegisterScript.cs @@ -58,4 +58,4 @@ private void ShowOutput(string message) Output.text = message; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/Login/LoginScript.cs b/sample/Assets/Scripts/Passport/Login/LoginScript.cs index 163b33fa..e0d75e70 100644 --- a/sample/Assets/Scripts/Passport/Login/LoginScript.cs +++ b/sample/Assets/Scripts/Passport/Login/LoginScript.cs @@ -1,5 +1,4 @@ using System; -using Cysharp.Threading.Tasks; using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; @@ -9,11 +8,10 @@ public class LoginScript : MonoBehaviour { #pragma warning disable CS8618 [SerializeField] private Text Output; - [SerializeField] private InputField DeviceCodeTimeoutMs; private Passport Passport; #pragma warning restore CS8618 - async void Start() + void Start() { if (Passport.Instance != null) { @@ -30,20 +28,10 @@ async void Start() /// public async void Login() { - var timeoutMs = GetDeviceCodeTimeoutMs(); - string formattedTimeout = timeoutMs != null ? $"{timeoutMs} ms" : "none"; - ShowOutput($"Logging in (timeout: {formattedTimeout})..."); try { - if (SampleAppManager.UsePKCE) - { - await Passport.LoginPKCE(); - } - else - { - await Passport.Login(timeoutMs: timeoutMs); - } - NavigateToAuthenticatedScene(); + await Passport.Login(); + SceneManager.LoadScene("AuthenticatedScene"); } catch (OperationCanceledException) { @@ -55,16 +43,6 @@ public async void Login() } } - private long? GetDeviceCodeTimeoutMs() - { - return string.IsNullOrEmpty(DeviceCodeTimeoutMs.text) ? null : long.Parse(DeviceCodeTimeoutMs.text); - } - - private void NavigateToAuthenticatedScene() - { - SceneManager.LoadScene("AuthenticatedScene"); - } - private void ShowOutput(string message) { if (Output != null) @@ -72,4 +50,4 @@ private void ShowOutput(string message) Output.text = message; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/Logout/LogoutScript.cs b/sample/Assets/Scripts/Passport/Logout/LogoutScript.cs index 1609f98c..8aba609a 100644 --- a/sample/Assets/Scripts/Passport/Logout/LogoutScript.cs +++ b/sample/Assets/Scripts/Passport/Logout/LogoutScript.cs @@ -22,14 +22,7 @@ private async UniTaskVoid LogoutAsync() } try { - if (SampleAppManager.UsePKCE) - { - await Passport.Instance.LogoutPKCE(); - } - else - { - await Passport.Instance.Logout(); - } + await Passport.Instance.Logout(); SampleAppManager.IsConnectedToImx = false; SampleAppManager.IsConnectedToZkEvm = false; AuthenticatedSceneManager.NavigateToUnauthenticatedScene(); @@ -39,4 +32,4 @@ private async UniTaskVoid LogoutAsync() Debug.LogError($"Failed to logout: {ex.Message}"); } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/Other/AuthenticatedSceneNavigation.cs b/sample/Assets/Scripts/Passport/Other/AuthenticatedSceneNavigation.cs index 71b30d25..7481c7ae 100644 --- a/sample/Assets/Scripts/Passport/Other/AuthenticatedSceneNavigation.cs +++ b/sample/Assets/Scripts/Passport/Other/AuthenticatedSceneNavigation.cs @@ -46,4 +46,4 @@ public void ShowLinkWallet() } // Add more navigation methods as needed for other features -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/Other/SetCallTimeout/SetCallTimeoutScript.cs b/sample/Assets/Scripts/Passport/Other/SetCallTimeout/SetCallTimeoutScript.cs index 9cc3a74a..e89a432c 100644 --- a/sample/Assets/Scripts/Passport/Other/SetCallTimeout/SetCallTimeoutScript.cs +++ b/sample/Assets/Scripts/Passport/Other/SetCallTimeout/SetCallTimeoutScript.cs @@ -46,4 +46,4 @@ private void ShowOutput(string message) Debug.LogWarning($"[SetCallTimeoutScript] Output Text is not assigned. Message: {message}"); } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/PassportInitialisation/PassportInitialisationScript.cs b/sample/Assets/Scripts/Passport/PassportInitialisation/PassportInitialisationScript.cs index 7bf70927..a6663ec6 100644 --- a/sample/Assets/Scripts/Passport/PassportInitialisation/PassportInitialisationScript.cs +++ b/sample/Assets/Scripts/Passport/PassportInitialisation/PassportInitialisationScript.cs @@ -10,59 +10,35 @@ public class PassportInitialisationScript : MonoBehaviour #pragma warning disable CS8618 [SerializeField] private GameObject TopPadding; [SerializeField] private Text Output; - [SerializeField] private Button UseDeviceCodeAuthButton; - [SerializeField] private Button UsePKCEButton; #pragma warning restore CS8618 void Start() { - // WebGL does not support Device Code Auth, so we'll use PKCE by default instead. -#if UNITY_WEBGL - UsePKCE(); -#endif + InitialisePassport(); } - /// - /// Initialises Passport to use Device Code Auth - /// - public void UseDeviceCodeAuth() + private async void InitialisePassport() { - SampleAppManager.UsePKCE = false; - InitialisePassport(logoutRedirectUri: "https://www.immutable.com"); - } + ShowOutput("Initialising Passport..."); + + string redirectUri; + string logoutRedirectUri; - /// - /// Initialises Passport to use PKCE with the specified redirect URIs. - /// - public void UsePKCE() - { - SampleAppManager.UsePKCE = true; #if UNITY_WEBGL - string url = Application.absoluteURL; - Uri uri = new Uri(url); - string scheme = uri.Scheme; - string hostWithPort = uri.IsDefaultPort ? uri.Host : $"{uri.Host}:{uri.Port}"; - string fullPath = uri.AbsolutePath.EndsWith("/") ? uri.AbsolutePath : uri.AbsolutePath.Substring(0, uri.AbsolutePath.LastIndexOf('/') + 1); + var url = Application.absoluteURL; + var uri = new Uri(url); + var scheme = uri.Scheme; + var hostWithPort = uri.IsDefaultPort ? uri.Host : $"{uri.Host}:{uri.Port}"; + var fullPath = uri.AbsolutePath.EndsWith("/") + ? uri.AbsolutePath + : uri.AbsolutePath.Substring(0, uri.AbsolutePath.LastIndexOf('/') + 1); - string redirectUri = $"{scheme}://{hostWithPort}{fullPath}callback.html"; - string logoutRedirectUri = $"{scheme}://{hostWithPort}{fullPath}logout.html"; - - InitialisePassport(redirectUri: redirectUri, logoutRedirectUri: logoutRedirectUri); + redirectUri = $"{scheme}://{hostWithPort}{fullPath}callback.html"; + logoutRedirectUri = $"{scheme}://{hostWithPort}{fullPath}logout.html"; #else - InitialisePassport(redirectUri: "immutablerunner://callback", logoutRedirectUri: "immutablerunner://logout"); + redirectUri = "immutablerunner://callback"; + logoutRedirectUri = "immutablerunner://logout"; #endif - } - - /// - /// Initialises Passport. - /// - /// The URL to which auth will redirect the browser after - /// authorisation has been granted by the user - /// The URL to which auth will redirect the browser - /// after log out is complete - private async void InitialisePassport(string? redirectUri = null, string? logoutRedirectUri = null) - { - ShowOutput("Initialising Passport..."); try { @@ -73,9 +49,9 @@ private async void InitialisePassport(string? redirectUri = null, string? logout Passport.RedactTokensInLogs = false; // Initialise Passport - string environment = Immutable.Passport.Model.Environment.SANDBOX; - string clientId = "mp6rxfMDwwZDogcdgNrAaHnG0qMlXuMK"; - Passport passport = await Passport.Init(clientId, environment, redirectUri, logoutRedirectUri); + const string environment = Immutable.Passport.Model.Environment.SANDBOX; + const string clientId = "mp6rxfMDwwZDogcdgNrAaHnG0qMlXuMK"; + var passport = await Passport.Init(clientId, environment, redirectUri, logoutRedirectUri); SampleAppManager.PassportInstance = passport; // Navigate to the unauthenticated scene after initialising Passport diff --git a/sample/Assets/Scripts/Passport/Reconnect/ReconnectScript.cs b/sample/Assets/Scripts/Passport/Reconnect/ReconnectScript.cs index 56030b23..1f5f1028 100644 --- a/sample/Assets/Scripts/Passport/Reconnect/ReconnectScript.cs +++ b/sample/Assets/Scripts/Passport/Reconnect/ReconnectScript.cs @@ -1,6 +1,5 @@ using UnityEngine; using UnityEngine.UI; -using UnityEngine.SceneManagement; using Cysharp.Threading.Tasks; using Immutable.Passport; @@ -64,4 +63,4 @@ private void ShowOutput(string message) Output.text = message; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/Relogin/ReloginScript.cs b/sample/Assets/Scripts/Passport/Relogin/ReloginScript.cs index e4876ce2..db583fe6 100644 --- a/sample/Assets/Scripts/Passport/Relogin/ReloginScript.cs +++ b/sample/Assets/Scripts/Passport/Relogin/ReloginScript.cs @@ -54,4 +54,4 @@ private void ShowOutput(string message) Output.text = message; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/SampleAppManager.cs b/sample/Assets/Scripts/Passport/SampleAppManager.cs index e216ab24..e2100bda 100644 --- a/sample/Assets/Scripts/Passport/SampleAppManager.cs +++ b/sample/Assets/Scripts/Passport/SampleAppManager.cs @@ -1,10 +1,5 @@ public static class SampleAppManager { - /// - /// Indicates whether the selected authentication method is PKCE. - /// - public static bool UsePKCE { get; set; } - /// /// Indicates whether the user is connected to IMX. /// @@ -19,4 +14,4 @@ public static class SampleAppManager /// Holds the Passport instance for IMX operations. /// public static Immutable.Passport.Passport PassportInstance { get; set; } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/UnauthenticatedSceneManager.cs b/sample/Assets/Scripts/Passport/UnauthenticatedSceneManager.cs index 58cda90f..1aa6fd64 100644 --- a/sample/Assets/Scripts/Passport/UnauthenticatedSceneManager.cs +++ b/sample/Assets/Scripts/Passport/UnauthenticatedSceneManager.cs @@ -1,6 +1,4 @@ using UnityEngine; -using UnityEngine.UI; -using Cysharp.Threading.Tasks; using Immutable.Passport; using System; @@ -8,7 +6,6 @@ public class UnauthenticatedSceneManager : MonoBehaviour { [SerializeField] private GameObject LoginButtons; [SerializeField] private GameObject ReloginButtons; - [SerializeField] private InputField DeviceCodeTimeoutMs; public Action OnImxConnected; @@ -16,10 +13,9 @@ private async void Start() { if (Passport.Instance != null) { - bool hasCredsSaved = await Passport.Instance.HasCredentialsSaved(); - ReloginButtons.SetActive(hasCredsSaved); - LoginButtons.SetActive(!hasCredsSaved); - DeviceCodeTimeoutMs.gameObject.SetActive(!hasCredsSaved && !SampleAppManager.UsePKCE); + var hasCredentialsSaved = await Passport.Instance.HasCredentialsSaved(); + ReloginButtons.SetActive(hasCredentialsSaved); + LoginButtons.SetActive(!hasCredentialsSaved); } else { @@ -31,4 +27,4 @@ void Awake() { OnImxConnected = () => { UnityEngine.SceneManagement.SceneManager.LoadScene("AuthenticatedScene"); }; } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmConnect/ZkEvmConnectScript.cs b/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmConnect/ZkEvmConnectScript.cs index cdf464da..0326b80e 100644 --- a/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmConnect/ZkEvmConnectScript.cs +++ b/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmConnect/ZkEvmConnectScript.cs @@ -1,8 +1,6 @@ -using System; using UnityEngine; using UnityEngine.UI; using Cysharp.Threading.Tasks; -using Immutable.Passport; namespace Immutable.Passport.Sample.PassportFeatures { @@ -31,7 +29,7 @@ private async UniTaskVoid ConnectZkEvmAsync() try { await Passport.Instance.ConnectEvm(); - + // Add these lines to update connection state and refresh UI SampleAppManager.IsConnectedToZkEvm = true; var sceneManager = FindObjectOfType(); @@ -44,7 +42,7 @@ private async UniTaskVoid ConnectZkEvmAsync() { Debug.LogWarning("Could not find AuthenticatedSceneManager to update button states"); } - + ShowOutput("Connected to EVM"); } catch (System.Exception ex) @@ -60,4 +58,4 @@ private void ShowOutput(string message) output.text = message; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmGetBalance/ZkEvmGetBalanceScript.cs b/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmGetBalance/ZkEvmGetBalanceScript.cs index ebd8de81..3a5603c8 100644 --- a/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmGetBalance/ZkEvmGetBalanceScript.cs +++ b/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmGetBalance/ZkEvmGetBalanceScript.cs @@ -52,4 +52,4 @@ private void ShowOutput(string message) Output.text = message; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmGetTransactionReceipt/ZkEvmGetTransactionReceiptScript.cs b/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmGetTransactionReceipt/ZkEvmGetTransactionReceiptScript.cs index 770e9ae7..4bf648c5 100644 --- a/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmGetTransactionReceipt/ZkEvmGetTransactionReceiptScript.cs +++ b/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmGetTransactionReceipt/ZkEvmGetTransactionReceiptScript.cs @@ -65,4 +65,4 @@ private void ShowOutput(string message) Output.text = message; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmSendTransaction/ZkEvmSendTransactionScript.cs b/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmSendTransaction/ZkEvmSendTransactionScript.cs index 909467d0..0ad5745d 100644 --- a/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmSendTransaction/ZkEvmSendTransactionScript.cs +++ b/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmSendTransaction/ZkEvmSendTransactionScript.cs @@ -3,7 +3,6 @@ using UnityEngine; using UnityEngine.UI; using UnityEngine.SceneManagement; -using Immutable.Passport; using Immutable.Passport.Model; using Cysharp.Threading.Tasks; @@ -23,7 +22,7 @@ void Start() ShowOutput("Passport instance is null"); return; } - + // Make sure UI elements are initialised if (ConfirmToggle != null && GetTransactionReceiptToggle != null) { @@ -66,7 +65,7 @@ private async UniTaskVoid SendTransactionAsync() value = ValueInputField != null ? ValueInputField.text : "", data = DataInputField != null ? DataInputField.text : "" }; - + if (ConfirmToggle != null && ConfirmToggle.isOn) { TransactionReceiptResponse response = await SampleAppManager.PassportInstance.ZkEvmSendTransactionWithConfirmation(request); @@ -75,7 +74,7 @@ private async UniTaskVoid SendTransactionAsync() else { string transactionHash = await SampleAppManager.PassportInstance.ZkEvmSendTransaction(request); - + if (GetTransactionReceiptToggle != null && GetTransactionReceiptToggle.isOn) { string? status = await PollStatus(transactionHash); @@ -150,4 +149,4 @@ private void ShowOutput(string message) Debug.Log($"ZkEvmSendTransactionScript: {message}"); } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmSignTypedData/ZkEvmSignTypedDataScript.cs b/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmSignTypedData/ZkEvmSignTypedDataScript.cs index d1a96444..7c3108f2 100644 --- a/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmSignTypedData/ZkEvmSignTypedDataScript.cs +++ b/sample/Assets/Scripts/Passport/ZkEvm/ZkEvmSignTypedData/ZkEvmSignTypedDataScript.cs @@ -47,4 +47,4 @@ private void ShowOutput(string message) Output.text = message; } } -} \ No newline at end of file +} \ No newline at end of file diff --git a/sample/ProjectSettings/EditorBuildSettings.asset b/sample/ProjectSettings/EditorBuildSettings.asset index d3a0ba7f..cb98e777 100644 --- a/sample/ProjectSettings/EditorBuildSettings.asset +++ b/sample/ProjectSettings/EditorBuildSettings.asset @@ -6,7 +6,7 @@ EditorBuildSettings: serializedVersion: 2 m_Scenes: - enabled: 1 - path: Assets/Scenes/Passport/SelectAuthMethod.unity + path: Assets/Scenes/Passport/Initialisation.unity guid: bb0668e0c95b745ce8e2f127d5940ede - enabled: 1 path: Assets/Scenes/Passport/UnauthenticatedScene.unity diff --git a/src/Packages/Passport/Runtime/Scripts/Private/Core/Model/BrowserResponse.cs b/src/Packages/Passport/Runtime/Scripts/Private/Core/Model/BrowserResponse.cs index f14298a3..ec897f8b 100644 --- a/src/Packages/Passport/Runtime/Scripts/Private/Core/Model/BrowserResponse.cs +++ b/src/Packages/Passport/Runtime/Scripts/Private/Core/Model/BrowserResponse.cs @@ -1,5 +1,3 @@ -using System; -using UnityEngine; using Immutable.Passport.Helpers; namespace Immutable.Passport.Core @@ -32,53 +30,32 @@ public static class BrowserResponseExtensions { /// /// Deserialises the json to StringResponse and returns the result - /// See + /// See /// - public static string GetStringResult(this string json) + public static string? GetStringResult(this string json) { - StringResponse stringResponse = json.OptDeserializeObject(); - if (stringResponse != null) - { - return stringResponse.result; - } - else - { - return null; - } + var stringResponse = json.OptDeserializeObject(); + return stringResponse?.result; } /// /// Deserialises the json to StringListResponse and returns the result - /// See + /// See /// - public static string[] GetStringListResult(this string json) + public static string[]? GetStringListResult(this string json) { - StringListResponse stringResponse = json.OptDeserializeObject(); - if (stringResponse != null) - { - return stringResponse.result; - } - else - { - return null; - } + var stringResponse = json.OptDeserializeObject(); + return stringResponse?.result; } /// /// Deserialises the json to BoolResponse and returns the result - /// See + /// See /// - public static Nullable GetBoolResponse(this string json) + public static bool? GetBoolResponse(this string json) { - BoolResponse boolResponse = json.OptDeserializeObject(); - if (boolResponse != null) - { - return boolResponse.result; - } - else - { - return null; - } + var boolResponse = json.OptDeserializeObject(); + return boolResponse?.result; } } } diff --git a/src/Packages/Passport/Runtime/Scripts/Private/Event/PassportAuthEvent.cs b/src/Packages/Passport/Runtime/Scripts/Private/Event/PassportAuthEvent.cs index f9f2e3f3..b27610cb 100644 --- a/src/Packages/Passport/Runtime/Scripts/Private/Event/PassportAuthEvent.cs +++ b/src/Packages/Passport/Runtime/Scripts/Private/Event/PassportAuthEvent.cs @@ -4,65 +4,6 @@ namespace Immutable.Passport.Event public enum PassportAuthEvent { - #region Device Code Authorisation - - /// - /// Started the login process using Device Code Authorisation flow - /// - LoggingIn, - /// - /// Failed to log in using Device Code Authorisation flow - /// - LoginFailed, - /// - /// Successfully logged in using Device Code Authorisation flow - /// - LoginSuccess, - /// - /// Opening Passport login in an external browser for login via Device Code Authorisation flow - /// - LoginOpeningBrowser, - /// - /// Waiting for user to complete Passport login in an external browser - /// - PendingBrowserLogin, - - /// - /// Started the login and set up IMX provider process using Device Code Authorisation flow - /// - ConnectingImx, - /// - /// Failed to login and set up IMX provider using Device Code Authorisation flow - /// - ConnectImxFailed, - /// - /// Successfully logged in and set up IMX provider using Device Code Authorisation flow - /// - ConnectImxSuccess, - /// - /// Opening Passport login in an external browser for connect IMX via Device Code Authorisation flow - /// - ConnectImxOpeningBrowser, - /// - /// Waiting for user to complete Passport login in the browser and the IMX provider to be set up - /// - PendingBrowserLoginAndProviderSetup, - - /// - /// Started the log out process using an external browser - /// - LoggingOut, - /// - /// Failed to log out using an external browser - /// - LogoutFailed, - /// - /// Successfully logged out using an external browser - /// - LogoutSuccess, - - #endregion - #region PKCE /// diff --git a/src/Packages/Passport/Runtime/Scripts/Private/Helpers/JsonHelpers.cs b/src/Packages/Passport/Runtime/Scripts/Private/Helpers/JsonHelpers.cs index 810f1497..1bf7c7b8 100644 --- a/src/Packages/Passport/Runtime/Scripts/Private/Helpers/JsonHelpers.cs +++ b/src/Packages/Passport/Runtime/Scripts/Private/Helpers/JsonHelpers.cs @@ -12,7 +12,7 @@ public static class JsonExtensions /// /// Return null if the deserialisation fails. /// - public static T OptDeserializeObject(this string json) where T : class + public static T? OptDeserializeObject(this string json) where T : class { try { diff --git a/src/Packages/Passport/Runtime/Scripts/Private/Model/Request/ConfirmCodeRequest.cs b/src/Packages/Passport/Runtime/Scripts/Private/Model/Request/ConfirmCodeRequest.cs deleted file mode 100644 index afc5c075..00000000 --- a/src/Packages/Passport/Runtime/Scripts/Private/Model/Request/ConfirmCodeRequest.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; - -namespace Immutable.Passport.Model -{ - [Serializable] - internal class ConfirmCodeRequest - { - public string deviceCode; - public int interval; - public long? timeoutMs; - } -} - diff --git a/src/Packages/Passport/Runtime/Scripts/Private/Model/Request/ConfirmCodeRequest.cs.meta b/src/Packages/Passport/Runtime/Scripts/Private/Model/Request/ConfirmCodeRequest.cs.meta deleted file mode 100644 index 6cb35330..00000000 --- a/src/Packages/Passport/Runtime/Scripts/Private/Model/Request/ConfirmCodeRequest.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: 48316801150940d4a8c2322fbeb97f65 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/Packages/Passport/Runtime/Scripts/Private/Model/Request/InitRequest.cs b/src/Packages/Passport/Runtime/Scripts/Private/Model/Request/InitRequest.cs index da20f9c7..1e63ae5a 100644 --- a/src/Packages/Passport/Runtime/Scripts/Private/Model/Request/InitRequest.cs +++ b/src/Packages/Passport/Runtime/Scripts/Private/Model/Request/InitRequest.cs @@ -11,13 +11,4 @@ internal class InitRequestWithRedirectUri public string logoutRedirectUri; public VersionInfo engineVersion; } - - [Serializable] - internal class InitRequest - { - public string clientId; - public string environment; - public string logoutRedirectUri; - public VersionInfo engineVersion; - } } diff --git a/src/Packages/Passport/Runtime/Scripts/Private/Model/Response/DeviceConnectResponse.cs b/src/Packages/Passport/Runtime/Scripts/Private/Model/Response/DeviceConnectResponse.cs deleted file mode 100644 index 5581fe71..00000000 --- a/src/Packages/Passport/Runtime/Scripts/Private/Model/Response/DeviceConnectResponse.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Immutable.Passport.Core; - -namespace Immutable.Passport.Model -{ - public class DeviceConnectResponse : BrowserResponse - { - public string code; - public string deviceCode; - public string url; - public int interval; - } -} diff --git a/src/Packages/Passport/Runtime/Scripts/Private/Model/Response/DeviceConnectResponse.cs.meta b/src/Packages/Passport/Runtime/Scripts/Private/Model/Response/DeviceConnectResponse.cs.meta deleted file mode 100644 index 350fe6d5..00000000 --- a/src/Packages/Passport/Runtime/Scripts/Private/Model/Response/DeviceConnectResponse.cs.meta +++ /dev/null @@ -1,11 +0,0 @@ -fileFormatVersion: 2 -guid: a694e18850cceba4b81ce05751bdd662 -MonoImporter: - externalObjects: {} - serializedVersion: 2 - defaultReferences: [] - executionOrder: 0 - icon: {instanceID: 0} - userData: - assetBundleName: - assetBundleVariant: diff --git a/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs b/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs index 71079db9..ecc8fa46 100644 --- a/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs +++ b/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs @@ -21,43 +21,39 @@ public class PassportImpl #endif { private const string TAG = "[Passport Implementation]"; - public readonly IBrowserCommunicationsManager communicationsManager; - private PassportAnalytics analytics = new(); + private readonly IBrowserCommunicationsManager _communicationsManager; + private readonly PassportAnalytics _analytics = new(); - // Used for device code auth - private DeviceConnectResponse? deviceConnectResponse; - - // Used for PKCE - private bool pkceLoginOnly; // Used to differentiate between a login and connect - private UniTaskCompletionSource? pkceCompletionSource; - private string? redirectUri; - private string? logoutRedirectUri; + private bool _pkceLoginOnly; // Used to differentiate between a login and connect + private UniTaskCompletionSource? _pkceCompletionSource; + private string _redirectUri; + private string _logoutRedirectUri; #if UNITY_ANDROID // Used for the PKCE callback - internal static bool completingPKCE = false; + internal static bool completingPKCE; internal static string loginPKCEUrl; #endif // Used to prevent calling login/connect functions multiple times - private bool isLoggedIn = false; + private bool _isLoggedIn; public event OnAuthEventDelegate? OnAuthEvent; public PassportImpl(IBrowserCommunicationsManager communicationsManager) { - this.communicationsManager = communicationsManager; + _communicationsManager = communicationsManager; } - public async UniTask Init(string clientId, string environment, string? redirectUri = null, - string? logoutRedirectUri = null, string? deeplink = null) + public async UniTask Init(string clientId, string environment, string redirectUri, + string logoutRedirectUri, string? deeplink = null) { - this.redirectUri = redirectUri; - this.logoutRedirectUri = logoutRedirectUri; + _redirectUri = redirectUri; + _logoutRedirectUri = logoutRedirectUri; #if (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL - this.communicationsManager.OnAuthPostMessage += OnDeepLinkActivated; - this.communicationsManager.OnPostMessageError += OnPostMessageError; + _communicationsManager.OnAuthPostMessage += OnDeepLinkActivated; + _communicationsManager.OnPostMessageError += OnPostMessageError; #endif var versionInfo = new VersionInfo @@ -70,35 +66,19 @@ public async UniTask Init(string clientId, string environment, string? redirectU deviceModel = SystemInfo.deviceModel }; - string initRequest; - if (redirectUri != null) - { - InitRequestWithRedirectUri requestWithRedirectUri = new InitRequestWithRedirectUri() - { - clientId = clientId, - environment = environment, - redirectUri = redirectUri, - logoutRedirectUri = logoutRedirectUri, - engineVersion = versionInfo - }; - initRequest = JsonUtility.ToJson(requestWithRedirectUri); - } - else + var initRequest = JsonUtility.ToJson(new InitRequestWithRedirectUri { - InitRequest request = new InitRequest - { - clientId = clientId, - environment = environment, - logoutRedirectUri = logoutRedirectUri, - engineVersion = versionInfo - }; - initRequest = JsonUtility.ToJson(request); - } + clientId = clientId, + environment = environment, + redirectUri = redirectUri, + logoutRedirectUri = logoutRedirectUri, + engineVersion = versionInfo + }); - string response = await communicationsManager.Call(PassportFunction.INIT, initRequest); - BrowserResponse initResponse = response.OptDeserializeObject(); + var response = await _communicationsManager.Call(PassportFunction.INIT, initRequest); + var initResponse = response.OptDeserializeObject(); - if (initResponse.success == false) + if (initResponse?.success == false) { Track(PassportAnalytics.EventName.INIT_PASSPORT, success: false); throw new PassportException(initResponse.error ?? "Unable to initialise Passport"); @@ -112,34 +92,40 @@ public async UniTask Init(string clientId, string environment, string? redirectU Track(PassportAnalytics.EventName.INIT_PASSPORT, success: true); } - public async UniTask Login(bool useCachedSession = false, Nullable timeoutMs = null) + public void SetCallTimeout(int ms) + { + _communicationsManager.SetCallTimeout(ms); + } + + public UniTask Login(bool useCachedSession = false) { if (useCachedSession) { - return await Relogin(); + return Relogin(); } try { - const string functionName = "Login"; - Track(PassportAnalytics.EventName.START_LOGIN); - SendAuthEvent(PassportAuthEvent.LoggingIn); - - await InitialiseDeviceCodeAuth(functionName); - await ConfirmCode( - PassportAuthEvent.LoginOpeningBrowser, PassportAuthEvent.PendingBrowserLogin, functionName, - PassportFunction.LOGIN_CONFIRM_CODE, timeoutMs); + Track(PassportAnalytics.EventName.START_LOGIN_PKCE); + SendAuthEvent(PassportAuthEvent.LoggingInPKCE); - Track(PassportAnalytics.EventName.COMPLETE_LOGIN, success: true); - SendAuthEvent(PassportAuthEvent.LoginSuccess); - isLoggedIn = true; - return true; + var task = new UniTaskCompletionSource(); + _pkceCompletionSource = task; + _pkceLoginOnly = true; +#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) + WindowsDeepLink.Initialise(redirectUri, OnDeepLinkActivated); +#endif + _ = LaunchAuthUrl(); + return task.Task; } catch (Exception ex) { - Track(PassportAnalytics.EventName.COMPLETE_LOGIN, success: false); - SendAuthEvent(PassportAuthEvent.LoginFailed); - throw ex; + var errorMessage = $"Failed to log in using PKCE flow: {ex.Message}"; + PassportLogger.Error($"{TAG} {errorMessage}"); + + Track(PassportAnalytics.EventName.COMPLETE_LOGIN_PKCE, success: false); + SendAuthEvent(PassportAuthEvent.LoginPKCEFailed); + throw new PassportException(errorMessage, PassportErrorType.AUTHENTICATION_ERROR); } } @@ -155,10 +141,10 @@ private async UniTask Relogin() { SendAuthEvent(PassportAuthEvent.ReloggingIn); - string callResponse = await communicationsManager.Call(PassportFunction.RELOGIN); + string callResponse = await _communicationsManager.Call(PassportFunction.RELOGIN); Track(PassportAnalytics.EventName.COMPLETE_RELOGIN, success: true); SendAuthEvent(PassportAuthEvent.ReloginSuccess); - isLoggedIn = true; + _isLoggedIn = true; return true; } @@ -167,7 +153,7 @@ private async UniTask Relogin() // Log a warning if re-login fails. PassportLogger.Warn($"{TAG} Failed to login using saved credentials. " + $"Please check if user has saved credentials first by calling HasCredentialsSaved() : {ex.Message}"); - isLoggedIn = false; + _isLoggedIn = false; } Track(PassportAnalytics.EventName.COMPLETE_RELOGIN, success: false); @@ -175,47 +161,48 @@ private async UniTask Relogin() return false; } - public async UniTask ConnectImx(bool useCachedSession = false, long? timeoutMs = null) + public async UniTask ConnectImx(bool useCachedSession = false) { if (useCachedSession) { return await Reconnect(); } - // If the user called Login before and then ConnectImx, there is no point triggering device flow again - bool hasCredsSaved = await HasCredentialsSaved(); - if (hasCredsSaved) + // If the user called Login before and then ConnectImx, there is no point triggering full login flow again + if (await HasCredentialsSaved()) { - bool reconnected = await Reconnect(); - if (reconnected) + var reconnected = await Reconnect(); + if (await Reconnect()) { // Successfully reconnected return reconnected; } - // Otherwise fallback to device code flow + // Otherwise fallback to login } try { - const string functionName = "ConnectImx"; - Track(PassportAnalytics.EventName.START_CONNECT_IMX); - SendAuthEvent(PassportAuthEvent.ConnectingImx); + Track(PassportAnalytics.EventName.START_CONNECT_IMX_PKCE); + SendAuthEvent(PassportAuthEvent.ConnectingImxPKCE); + UniTaskCompletionSource task = new UniTaskCompletionSource(); + _pkceCompletionSource = task; + _pkceLoginOnly = false; - await InitialiseDeviceCodeAuth(functionName); - await ConfirmCode( - PassportAuthEvent.ConnectImxOpeningBrowser, PassportAuthEvent.PendingBrowserLoginAndProviderSetup, - functionName, PassportFunction.CONNECT_CONFIRM_CODE, timeoutMs); +#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) + WindowsDeepLink.Initialise(redirectUri, OnDeepLinkActivated); +#endif - Track(PassportAnalytics.EventName.COMPLETE_CONNECT_IMX, success: true); - SendAuthEvent(PassportAuthEvent.ConnectImxSuccess); - isLoggedIn = true; - return true; + _ = LaunchAuthUrl(); + return await task.Task; } catch (Exception ex) { - Track(PassportAnalytics.EventName.COMPLETE_CONNECT_IMX, success: false); - SendAuthEvent(PassportAuthEvent.ConnectImxFailed); - throw ex; + var errorMessage = $"Failed to connect using PKCE flow: {ex.Message}"; + PassportLogger.Error($"{TAG} {errorMessage}"); + + Track(PassportAnalytics.EventName.COMPLETE_CONNECT_IMX_PKCE, success: false); + SendAuthEvent(PassportAuthEvent.ConnectImxPKCEFailed); + throw new PassportException(errorMessage, PassportErrorType.AUTHENTICATION_ERROR); } } @@ -229,11 +216,11 @@ private async UniTask Reconnect() { SendAuthEvent(PassportAuthEvent.Reconnecting); - string callResponse = await communicationsManager.Call(PassportFunction.RECONNECT); + string callResponse = await _communicationsManager.Call(PassportFunction.RECONNECT); Track(PassportAnalytics.EventName.COMPLETE_RECONNECT, success: true); SendAuthEvent(PassportAuthEvent.ReconnectSuccess); - isLoggedIn = true; + _isLoggedIn = true; return true; } catch (Exception ex) @@ -242,7 +229,7 @@ private async UniTask Reconnect() PassportLogger.Warn($"{TAG} Failed to connect using saved credentials. " + $"Please check if user has saved credentials first by calling HasCredentialsSaved() : {ex.Message}"); - isLoggedIn = false; + _isLoggedIn = false; } Track(PassportAnalytics.EventName.COMPLETE_RECONNECT, success: false); @@ -250,63 +237,6 @@ private async UniTask Reconnect() return false; } - private async UniTask InitialiseDeviceCodeAuth(string callingFunction) - { - string callResponse = await communicationsManager.Call(PassportFunction.INIT_DEVICE_FLOW); - deviceConnectResponse = callResponse.OptDeserializeObject(); - if (deviceConnectResponse != null && deviceConnectResponse.success == true) - { - return new ConnectResponse() - { - url = deviceConnectResponse.url, - code = deviceConnectResponse.code - }; - } - - throw new PassportException( - deviceConnectResponse?.error ?? $"Something went wrong, please call {callingFunction} again", - PassportErrorType.AUTHENTICATION_ERROR - ); - } - - private async UniTask ConfirmCode( - PassportAuthEvent openingBrowserAuthEvent, PassportAuthEvent pendingAuthEvent, - string callingFunction, string functionToCall, long? timeoutMs) - { - if (deviceConnectResponse != null) - { - long intervalMs = deviceConnectResponse.interval * 1000; - if (timeoutMs != null && timeoutMs < intervalMs) - { - throw new ArgumentException($"timeoutMs should be longer than {intervalMs}ms"); - } - - // Open URL for user to confirm - SendAuthEvent(openingBrowserAuthEvent); - OpenUrl(deviceConnectResponse.url); - - // Start polling for token - SendAuthEvent(pendingAuthEvent); - ConfirmCodeRequest request = new ConfirmCodeRequest() - { - deviceCode = deviceConnectResponse.deviceCode, - interval = deviceConnectResponse.interval, - timeoutMs = timeoutMs - }; - - string callResponse = await communicationsManager.Call( - functionToCall, - JsonUtility.ToJson(request), - ignoreTimeout: timeoutMs == null, - timeoutMs); - } - else - { - throw new PassportException($"Unable to confirm code, call {callingFunction} again", - PassportErrorType.AUTHENTICATION_ERROR); - } - } - public async void OnDeepLinkActivated(string url) { try @@ -323,11 +253,11 @@ public async void OnDeepLinkActivated(string url) domain = domain.Remove(domain.Length - 1); } - if (domain.Equals(logoutRedirectUri)) + if (domain.Equals(_logoutRedirectUri)) { - HandleLogoutPKCESuccess(); + HandleLogoutPkceSuccess(); } - else if (domain.Equals(redirectUri)) + else if (domain.Equals(_redirectUri)) { await CompleteLoginPKCEFlow(url); } @@ -338,66 +268,11 @@ public async void OnDeepLinkActivated(string url) } } - public UniTask LoginPKCE() - { - try - { - Track(PassportAnalytics.EventName.START_LOGIN_PKCE); - SendAuthEvent(PassportAuthEvent.LoggingInPKCE); - - UniTaskCompletionSource task = new UniTaskCompletionSource(); - pkceCompletionSource = task; - pkceLoginOnly = true; -#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) - WindowsDeepLink.Initialise(redirectUri, OnDeepLinkActivated); -#endif - _ = LaunchAuthUrl(); - return task.Task; - } - catch (Exception ex) - { - string errorMessage = $"Failed to log in using PKCE flow: {ex.Message}"; - PassportLogger.Error($"{TAG} {errorMessage}"); - - Track(PassportAnalytics.EventName.COMPLETE_LOGIN_PKCE, success: false); - SendAuthEvent(PassportAuthEvent.LoginPKCEFailed); - throw new PassportException(errorMessage, PassportErrorType.AUTHENTICATION_ERROR); - } - } - - public UniTask ConnectImxPKCE() - { - try - { - Track(PassportAnalytics.EventName.START_CONNECT_IMX_PKCE); - SendAuthEvent(PassportAuthEvent.ConnectingImxPKCE); - UniTaskCompletionSource task = new UniTaskCompletionSource(); - pkceCompletionSource = task; - pkceLoginOnly = false; - -#if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) - WindowsDeepLink.Initialise(redirectUri, OnDeepLinkActivated); -#endif - - _ = LaunchAuthUrl(); - return task.Task; - } - catch (Exception ex) - { - string errorMessage = $"Failed to connect using PKCE flow: {ex.Message}"; - PassportLogger.Error($"{TAG} {errorMessage}"); - - Track(PassportAnalytics.EventName.COMPLETE_CONNECT_IMX_PKCE, success: false); - SendAuthEvent(PassportAuthEvent.ConnectImxPKCEFailed); - throw new PassportException(errorMessage, PassportErrorType.AUTHENTICATION_ERROR); - } - } - private async UniTask LaunchAuthUrl() { try { - string callResponse = await communicationsManager.Call(PassportFunction.GET_PKCE_AUTH_URL); + string callResponse = await _communicationsManager.Call(PassportFunction.GET_PKCE_AUTH_URL); StringResponse response = callResponse.OptDeserializeObject(); if (response != null && response.success == true && response.result != null) @@ -408,24 +283,24 @@ private async UniTask LaunchAuthUrl() SendAuthEvent(pkceLoginOnly ? PassportAuthEvent.LoginPKCELaunchingCustomTabs : PassportAuthEvent.ConnectImxPKCELaunchingCustomTabs); LaunchAndroidUrl(url); #else - SendAuthEvent(pkceLoginOnly ? PassportAuthEvent.LoginPKCEOpeningWebView : PassportAuthEvent.ConnectImxPKCEOpeningWebView); - communicationsManager.LaunchAuthURL(url, redirectUri); + SendAuthEvent(_pkceLoginOnly ? PassportAuthEvent.LoginPKCEOpeningWebView : PassportAuthEvent.ConnectImxPKCEOpeningWebView); + _communicationsManager.LaunchAuthURL(url, _redirectUri); #endif return; } else { - PassportLogger.Error($"{TAG} Failed to get PKCE Auth URL"); + PassportLogger.Error($"{TAG} Failed to get the Auth URL"); } } catch (Exception e) { - PassportLogger.Error($"{TAG} Get PKCE Auth URL error: {e.Message}"); + PassportLogger.Error($"{TAG} Get the Auth URL error: {e.Message}"); } await UniTask.SwitchToMainThread(); - TrySetPKCEException(new PassportException( - "Something went wrong, please call LoginPKCE() or ConnectImxPKCE() again", + TrySetPkceException(new PassportException( + "Something went wrong, please call Login() or ConnectImx() again", PassportErrorType.AUTHENTICATION_ERROR )); } @@ -437,80 +312,80 @@ public async UniTask CompleteLoginPKCEFlow(string uriString) #endif try { - SendAuthEvent(pkceLoginOnly ? PassportAuthEvent.CompletingLoginPKCE : PassportAuthEvent.CompletingConnectImxPKCE); - Uri uri = new Uri(uriString); - string state = uri.GetQueryParameter("state"); - string authCode = uri.GetQueryParameter("code"); + SendAuthEvent(_pkceLoginOnly ? PassportAuthEvent.CompletingLoginPKCE : PassportAuthEvent.CompletingConnectImxPKCE); + var uri = new Uri(uriString); + var state = uri.GetQueryParameter("state"); + var authCode = uri.GetQueryParameter("code"); - if (String.IsNullOrEmpty(state) || String.IsNullOrEmpty(authCode)) + if (string.IsNullOrEmpty(state) || string.IsNullOrEmpty(authCode)) { Track( - pkceLoginOnly ? PassportAnalytics.EventName.COMPLETE_LOGIN_PKCE : PassportAnalytics.EventName.COMPLETE_CONNECT_IMX_PKCE, + _pkceLoginOnly ? PassportAnalytics.EventName.COMPLETE_LOGIN_PKCE : PassportAnalytics.EventName.COMPLETE_CONNECT_IMX_PKCE, success: false ); - SendAuthEvent(pkceLoginOnly ? PassportAuthEvent.LoginPKCEFailed : PassportAuthEvent.ConnectImxPKCEFailed); + SendAuthEvent(_pkceLoginOnly ? PassportAuthEvent.LoginPKCEFailed : PassportAuthEvent.ConnectImxPKCEFailed); await UniTask.SwitchToMainThread(); - TrySetPKCEException(new PassportException( + TrySetPkceException(new PassportException( "Uri was missing state and/or code. Please call ConnectImxPKCE() again", PassportErrorType.AUTHENTICATION_ERROR )); } else { - ConnectPKCERequest request = new ConnectPKCERequest() + var request = new ConnectPKCERequest() { authorizationCode = authCode, state = state }; - string callResponse = await communicationsManager.Call( - pkceLoginOnly ? PassportFunction.LOGIN_PKCE : PassportFunction.CONNECT_PKCE, + var callResponse = await _communicationsManager.Call( + _pkceLoginOnly ? PassportFunction.LOGIN_PKCE : PassportFunction.CONNECT_PKCE, JsonUtility.ToJson(request) ); - BrowserResponse response = callResponse.OptDeserializeObject(); + var response = callResponse.OptDeserializeObject(); await UniTask.SwitchToMainThread(); if (response != null && response.success != true) { Track( - pkceLoginOnly ? PassportAnalytics.EventName.COMPLETE_LOGIN_PKCE : PassportAnalytics.EventName.COMPLETE_CONNECT_IMX_PKCE, + _pkceLoginOnly ? PassportAnalytics.EventName.COMPLETE_LOGIN_PKCE : PassportAnalytics.EventName.COMPLETE_CONNECT_IMX_PKCE, success: false ); - SendAuthEvent(pkceLoginOnly ? PassportAuthEvent.LoginPKCEFailed : PassportAuthEvent.ConnectImxPKCEFailed); - TrySetPKCEException(new PassportException( - response.error ?? "Something went wrong, please call ConnectImxPKCE() again", + SendAuthEvent(_pkceLoginOnly ? PassportAuthEvent.LoginPKCEFailed : PassportAuthEvent.ConnectImxPKCEFailed); + TrySetPkceException(new PassportException( + response.error ?? "Something went wrong, please call ConnectImx() again", PassportErrorType.AUTHENTICATION_ERROR )); } else { - if (!isLoggedIn) + if (!_isLoggedIn) { - TrySetPKCEResult(true); + TrySetPkceResult(true); } Track( - pkceLoginOnly ? PassportAnalytics.EventName.COMPLETE_LOGIN_PKCE : PassportAnalytics.EventName.COMPLETE_CONNECT_IMX_PKCE, + _pkceLoginOnly ? PassportAnalytics.EventName.COMPLETE_LOGIN_PKCE : PassportAnalytics.EventName.COMPLETE_CONNECT_IMX_PKCE, success: true ); - SendAuthEvent(pkceLoginOnly ? PassportAuthEvent.LoginPKCESuccess : PassportAuthEvent.ConnectImxPKCESuccess); - isLoggedIn = true; + SendAuthEvent(_pkceLoginOnly ? PassportAuthEvent.LoginPKCESuccess : PassportAuthEvent.ConnectImxPKCESuccess); + _isLoggedIn = true; } } } catch (Exception ex) { Track( - pkceLoginOnly ? PassportAnalytics.EventName.COMPLETE_LOGIN_PKCE : PassportAnalytics.EventName.COMPLETE_CONNECT_IMX_PKCE, + _pkceLoginOnly ? PassportAnalytics.EventName.COMPLETE_LOGIN_PKCE : PassportAnalytics.EventName.COMPLETE_CONNECT_IMX_PKCE, success: false ); - SendAuthEvent(pkceLoginOnly ? PassportAuthEvent.LoginPKCEFailed : PassportAuthEvent.ConnectImxPKCEFailed); + SendAuthEvent(_pkceLoginOnly ? PassportAuthEvent.LoginPKCEFailed : PassportAuthEvent.ConnectImxPKCEFailed); // Ensure any failure results in completing the flow regardless. - TrySetPKCEException(ex); + TrySetPkceException(ex); } - pkceCompletionSource = null; + _pkceCompletionSource = null; #if UNITY_ANDROID completingPKCE = false; #endif @@ -519,11 +394,11 @@ public async UniTask CompleteLoginPKCEFlow(string uriString) #if UNITY_ANDROID public void OnLoginPKCEDismissed(bool completing) { - if (!completing && !isLoggedIn) + if (!completing && !_isLoggedIn) { // User hasn't entered all required details (e.g. email address) into Passport yet PassportLogger.Info($"{TAG} Login PKCE dismissed before completing the flow"); - TrySetPKCECanceled(); + TrySetPkceCanceled(); } else { @@ -538,64 +413,35 @@ public void OnDeeplinkResult(string url) } #endif - public async UniTask GetLogoutUrl() + private async UniTask GetLogoutUrl() { - string response = await communicationsManager.Call(PassportFunction.LOGOUT); - string logoutUrl = response.GetStringResult(); + var response = await _communicationsManager.Call(PassportFunction.LOGOUT); + var logoutUrl = response.GetStringResult(); if (string.IsNullOrEmpty(logoutUrl)) { throw new PassportException("Failed to get logout URL", PassportErrorType.AUTHENTICATION_ERROR); } - else - { - return response.GetStringResult(); - } - } - - public async UniTask Logout(bool hardLogout = true) - { - try - { - SendAuthEvent(PassportAuthEvent.LoggingOut); - - if (hardLogout) - { - var logoutUrl = await GetLogoutUrl(); - OpenUrl(logoutUrl); - } - - Track(PassportAnalytics.EventName.COMPLETE_LOGOUT, success: true); - SendAuthEvent(PassportAuthEvent.LogoutSuccess); - isLoggedIn = false; - } - catch (Exception ex) - { - string errorMessage = $"Failed to log out: {ex.Message}"; - PassportLogger.Error($"{TAG} {errorMessage}"); - Track(PassportAnalytics.EventName.COMPLETE_LOGOUT, success: false); - SendAuthEvent(PassportAuthEvent.LogoutFailed); - throw new PassportException(errorMessage, PassportErrorType.AUTHENTICATION_ERROR); - } + return logoutUrl; } - public UniTask LogoutPKCE(bool hardLogout = true) + public async UniTask Logout(bool hardLogout = true) { try { SendAuthEvent(PassportAuthEvent.LoggingOutPKCE); - UniTaskCompletionSource task = new UniTaskCompletionSource(); - pkceCompletionSource = task; + var task = new UniTaskCompletionSource(); + _pkceCompletionSource = task; #if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) WindowsDeepLink.Initialise(logoutRedirectUri, OnDeepLinkActivated); #endif - LaunchLogoutPKCEUrl(hardLogout); - return task.Task; + LaunchLogoutPkceUrl(hardLogout); + return await task.Task; } catch (Exception ex) { - string errorMessage = $"Failed to log out: {ex.Message}"; + var errorMessage = $"Failed to log out: {ex.Message}"; PassportLogger.Error($"{TAG} {errorMessage}"); Track(PassportAnalytics.EventName.COMPLETE_LOGOUT_PKCE, success: false); @@ -604,33 +450,33 @@ public UniTask LogoutPKCE(bool hardLogout = true) } } - private async void HandleLogoutPKCESuccess() + private async void HandleLogoutPkceSuccess() { await UniTask.SwitchToMainThread(); - if (isLoggedIn) + if (_isLoggedIn) { - TrySetPKCEResult(true); + TrySetPkceResult(true); } Track(PassportAnalytics.EventName.COMPLETE_LOGOUT_PKCE, success: true); SendAuthEvent(PassportAuthEvent.LogoutPKCESuccess); - isLoggedIn = false; - pkceCompletionSource = null; + _isLoggedIn = false; + _pkceCompletionSource = null; } - private async void LaunchLogoutPKCEUrl(bool hardLogout) + private async void LaunchLogoutPkceUrl(bool hardLogout) { - string logoutUrl = await GetLogoutUrl(); + var logoutUrl = await GetLogoutUrl(); if (hardLogout) { #if UNITY_ANDROID && !UNITY_EDITOR LaunchAndroidUrl(logoutUrl); #else - communicationsManager.LaunchAuthURL(logoutUrl, logoutRedirectUri); + _communicationsManager.LaunchAuthURL(logoutUrl, _logoutRedirectUri); #endif } else { - HandleLogoutPKCESuccess(); + HandleLogoutPkceSuccess(); } } @@ -639,89 +485,89 @@ public async UniTask HasCredentialsSaved() try { SendAuthEvent(PassportAuthEvent.CheckingForSavedCredentials); - string accessToken = await GetAccessToken(); - string idToken = await GetIdToken(); + var accessToken = await GetAccessToken(); + var idToken = await GetIdToken(); SendAuthEvent(PassportAuthEvent.CheckForSavedCredentialsSuccess); return accessToken != null && idToken != null; } catch (Exception ex) { - string errorMessage = $"Failed to check if there are credentials saved: {ex.Message}"; + var errorMessage = $"Failed to check if there are credentials saved: {ex.Message}"; PassportLogger.Debug($"{TAG} {errorMessage}"); SendAuthEvent(PassportAuthEvent.CheckForSavedCredentialsFailed); return false; } } - public async UniTask GetAddress() + public async UniTask GetAddress() { - string response = await communicationsManager.Call(PassportFunction.IMX.GET_ADDRESS); + var response = await _communicationsManager.Call(PassportFunction.IMX.GET_ADDRESS); return response.GetStringResult(); } public async UniTask IsRegisteredOffchain() { - string response = await communicationsManager.Call(PassportFunction.IMX.IS_REGISTERED_OFFCHAIN); + var response = await _communicationsManager.Call(PassportFunction.IMX.IS_REGISTERED_OFFCHAIN); return response.GetBoolResponse() ?? false; } - public async UniTask RegisterOffchain() + public async UniTask RegisterOffchain() { - string callResponse = await communicationsManager.Call(PassportFunction.IMX.REGISTER_OFFCHAIN); + var callResponse = await _communicationsManager.Call(PassportFunction.IMX.REGISTER_OFFCHAIN); return callResponse.OptDeserializeObject(); } - public async UniTask GetEmail() + public async UniTask GetEmail() { - string response = await communicationsManager.Call(PassportFunction.GET_EMAIL); + var response = await _communicationsManager.Call(PassportFunction.GET_EMAIL); return response.GetStringResult(); } - public async UniTask GetPassportId() + public async UniTask GetPassportId() { - string response = await communicationsManager.Call(PassportFunction.GET_PASSPORT_ID); + var response = await _communicationsManager.Call(PassportFunction.GET_PASSPORT_ID); return response.GetStringResult(); } - public async UniTask GetAccessToken() + public async UniTask GetAccessToken() { - string response = await communicationsManager.Call(PassportFunction.GET_ACCESS_TOKEN); + var response = await _communicationsManager.Call(PassportFunction.GET_ACCESS_TOKEN); return response.GetStringResult(); } - public async UniTask GetIdToken() + public async UniTask GetIdToken() { - string response = await communicationsManager.Call(PassportFunction.GET_ID_TOKEN); + var response = await _communicationsManager.Call(PassportFunction.GET_ID_TOKEN); return response.GetStringResult(); } public async UniTask> GetLinkedAddresses() { - string response = await communicationsManager.Call(PassportFunction.GET_LINKED_ADDRESSES); - string[] addresses = response.GetStringListResult(); + var response = await _communicationsManager.Call(PassportFunction.GET_LINKED_ADDRESSES); + var addresses = response.GetStringListResult(); return addresses != null ? addresses.ToList() : new List(); } // Imx - public async UniTask ImxTransfer(UnsignedTransferRequest request) + public async UniTask ImxTransfer(UnsignedTransferRequest request) { - string json = JsonUtility.ToJson(request); - string callResponse = await communicationsManager.Call(PassportFunction.IMX.TRANSFER, json); + var json = JsonUtility.ToJson(request); + var callResponse = await _communicationsManager.Call(PassportFunction.IMX.TRANSFER, json); return callResponse.OptDeserializeObject(); } - public async UniTask ImxBatchNftTransfer(NftTransferDetails[] details) + public async UniTask ImxBatchNftTransfer(NftTransferDetails[] details) { - string json = details.ToJson(); - string callResponse = await communicationsManager.Call(PassportFunction.IMX.BATCH_NFT_TRANSFER, json); + var json = details.ToJson(); + var callResponse = await _communicationsManager.Call(PassportFunction.IMX.BATCH_NFT_TRANSFER, json); return callResponse.OptDeserializeObject(); } // ZkEvm public async UniTask ConnectEvm() { - await communicationsManager.Call(PassportFunction.ZK_EVM.CONNECT_EVM); + await _communicationsManager.Call(PassportFunction.ZK_EVM.CONNECT_EVM); } private string SerialiseTransactionRequest(TransactionRequest request) @@ -729,7 +575,7 @@ private string SerialiseTransactionRequest(TransactionRequest request) string json; // Nulls are serialised as empty strings when using JsonUtility // so we need to use another model that doesn't have the 'data' field instead - if (String.IsNullOrEmpty(request.data)) + if (string.IsNullOrEmpty(request.data)) { json = JsonUtility.ToJson(new TransactionRequestNoData() { @@ -744,57 +590,57 @@ private string SerialiseTransactionRequest(TransactionRequest request) return json; } - public async UniTask ZkEvmSendTransaction(TransactionRequest request) + public async UniTask ZkEvmSendTransaction(TransactionRequest request) { - string json = SerialiseTransactionRequest(request); - string callResponse = await communicationsManager.Call(PassportFunction.ZK_EVM.SEND_TRANSACTION, json); + var json = SerialiseTransactionRequest(request); + var callResponse = await _communicationsManager.Call(PassportFunction.ZK_EVM.SEND_TRANSACTION, json); return callResponse.GetStringResult(); } - public async UniTask ZkEvmSendTransactionWithConfirmation(TransactionRequest request) + public async UniTask ZkEvmSendTransactionWithConfirmation(TransactionRequest request) { - string json = SerialiseTransactionRequest(request); - string callResponse = await communicationsManager.Call(PassportFunction.ZK_EVM.SEND_TRANSACTION_WITH_CONFIRMATION, json); + var json = SerialiseTransactionRequest(request); + var callResponse = await _communicationsManager.Call(PassportFunction.ZK_EVM.SEND_TRANSACTION_WITH_CONFIRMATION, json); return callResponse.OptDeserializeObject(); } - public async UniTask ZkEvmGetTransactionReceipt(string hash) + public async UniTask ZkEvmGetTransactionReceipt(string hash) { - string json = JsonUtility.ToJson(new TransactionReceiptRequest() + var json = JsonUtility.ToJson(new TransactionReceiptRequest() { txHash = hash }); - string jsonResponse = await communicationsManager.Call(PassportFunction.ZK_EVM.GET_TRANSACTION_RECEIPT, json); + var jsonResponse = await _communicationsManager.Call(PassportFunction.ZK_EVM.GET_TRANSACTION_RECEIPT, json); return jsonResponse.OptDeserializeObject(); } - public async UniTask ZkEvmSignTypedDataV4(string payload) + public async UniTask ZkEvmSignTypedDataV4(string payload) { - var callResponse = await communicationsManager.Call(PassportFunction.ZK_EVM.SIGN_TYPED_DATA_V4, payload); + var callResponse = await _communicationsManager.Call(PassportFunction.ZK_EVM.SIGN_TYPED_DATA_V4, payload); return callResponse.GetStringResult(); } public async UniTask> ZkEvmRequestAccounts() { - string callResponse = await communicationsManager.Call(PassportFunction.ZK_EVM.REQUEST_ACCOUNTS); - RequestAccountsResponse accountsResponse = callResponse.OptDeserializeObject(); + var callResponse = await _communicationsManager.Call(PassportFunction.ZK_EVM.REQUEST_ACCOUNTS); + var accountsResponse = callResponse.OptDeserializeObject(); return accountsResponse != null ? accountsResponse.accounts.ToList() : new List(); } public async UniTask ZkEvmGetBalance(string address, string blockNumberOrTag) { - string json = JsonUtility.ToJson(new GetBalanceRequest() + var json = JsonUtility.ToJson(new GetBalanceRequest() { address = address, blockNumberOrTag = blockNumberOrTag }); - string callResponse = await communicationsManager.Call(PassportFunction.ZK_EVM.GET_BALANCE, json); + var callResponse = await _communicationsManager.Call(PassportFunction.ZK_EVM.GET_BALANCE, json); return callResponse.GetStringResult() ?? "0x0"; } private async void OnPostMessageError(string id, string message) { - if (id == "CallFromAuthCallbackError" && pkceCompletionSource != null) + if (id == "CallFromAuthCallbackError" && _pkceCompletionSource != null) { await CallFromAuthCallbackError(id, message); } @@ -811,26 +657,26 @@ private async UniTask CallFromAuthCallbackError(string id, string message) if (message == "") { PassportLogger.Warn($"{TAG} Get PKCE Auth URL user cancelled"); - TrySetPKCECanceled(); + TrySetPkceCanceled(); } else { PassportLogger.Error($"{TAG} Get PKCE Auth URL error: {message}"); - TrySetPKCEException(new PassportException( + TrySetPkceException(new PassportException( "Something went wrong, please call LoginPKCE() or ConnectPKCEImx() again", PassportErrorType.AUTHENTICATION_ERROR )); } - pkceCompletionSource = null; + _pkceCompletionSource = null; } - private void TrySetPKCEResult(bool result) + private void TrySetPkceResult(bool result) { PassportLogger.Debug($"{TAG} Trying to set PKCE result to {result}..."); - if (pkceCompletionSource != null) + if (_pkceCompletionSource != null) { - pkceCompletionSource.TrySetResult(result); + _pkceCompletionSource.TrySetResult(result); } else { @@ -838,12 +684,12 @@ private void TrySetPKCEResult(bool result) } } - private void TrySetPKCEException(Exception exception) + private void TrySetPkceException(Exception exception) { PassportLogger.Debug($"{TAG} Trying to set PKCE exception..."); - if (pkceCompletionSource != null) + if (_pkceCompletionSource != null) { - pkceCompletionSource.TrySetException(exception); + _pkceCompletionSource.TrySetException(exception); } else { @@ -851,12 +697,12 @@ private void TrySetPKCEException(Exception exception) } } - private void TrySetPKCECanceled() + private void TrySetPkceCanceled() { PassportLogger.Debug($"{TAG} Trying to set PKCE canceled..."); - if (pkceCompletionSource != null) + if (_pkceCompletionSource != null) { - pkceCompletionSource.TrySetCanceled(); + _pkceCompletionSource.TrySetCanceled(); } else { @@ -899,7 +745,7 @@ public void ClearStorage() protected virtual async void Track(string eventName, bool? success = null, Dictionary properties = null) { - await analytics.Track(communicationsManager, eventName, success, properties); + await _analytics.Track(_communicationsManager, eventName, success, properties); } } diff --git a/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs b/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs index 1661f6fd..5415e107 100644 --- a/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs +++ b/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs @@ -34,20 +34,20 @@ public class Passport private const string TAG = "[Passport]"; public static Passport? Instance { get; private set; } - private PassportImpl? passportImpl; - public string environment { get; private set; } + private PassportImpl? _passportImpl; + public string Environment { get; private set; } - private IWebBrowserClient webBrowserClient; + private IWebBrowserClient _webBrowserClient; // Keeps track of the latest received deeplink - private static string? deeplink; - private static bool readySignalReceived; + private static string? _deeplink; + private static bool _readySignalReceived; /// /// Passport auth events /// /// - public event OnAuthEventDelegate OnAuthEvent; + public event OnAuthEventDelegate? OnAuthEvent; /// /// Gets or sets the log level for the SDK. @@ -144,8 +144,8 @@ private Passport() public static UniTask Init( string clientId, string environment, - string redirectUri = null, - string logoutRedirectUri = null + string redirectUri, + string logoutRedirectUri #if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) , int engineStartupTimeoutMs = 60000, IWindowsWebBrowserClient windowsWebBrowserClient = null @@ -163,7 +163,7 @@ public static UniTask Init( #else Instance = new Passport(); #endif - Instance.environment = environment; + Instance.Environment = environment; // Start initialisation process return Instance.Initialise( @@ -175,14 +175,14 @@ public static UniTask Init( { // Wait for the ready signal PassportLogger.Info($"{TAG} Waiting for ready signal..."); - await UniTask.WaitUntil(() => readySignalReceived == true); + await UniTask.WaitUntil(() => _readySignalReceived == true); }) .ContinueWith(async () => { - if (readySignalReceived) + if (_readySignalReceived) { // Initialise Passport with provided parameters - await Instance.GetPassportImpl().Init(clientId, environment, redirectUri, logoutRedirectUri, deeplink); + await Instance.GetPassportImpl().Init(clientId, environment, redirectUri, logoutRedirectUri, _deeplink); return Instance; } else @@ -192,12 +192,10 @@ public static UniTask Init( } }); } - else - { - // Return the existing instance if already initialised - readySignalReceived = true; - return UniTask.FromResult(Instance); - } + + // Return the existing instance if already initialised + _readySignalReceived = true; + return UniTask.FromResult(Instance); } /// @@ -234,31 +232,31 @@ private async UniTask Initialise( } #elif (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL // Initialise default browser client for Android, iOS, and macOS - webBrowserClient = new GreeBrowserClient(); + _webBrowserClient = new GreeBrowserClient(); #else throw new PassportException("Platform not supported"); #endif // Set up browser communication - BrowserCommunicationsManager communicationsManager = new BrowserCommunicationsManager(webBrowserClient); + BrowserCommunicationsManager communicationsManager = new BrowserCommunicationsManager(_webBrowserClient); #if UNITY_WEBGL readySignalReceived = true; #else // Mark ready when browser is initialised and game bridge file is loaded - communicationsManager.OnReady += () => readySignalReceived = true; + communicationsManager.OnReady += () => _readySignalReceived = true; #endif // Set up Passport implementation - passportImpl = new PassportImpl(communicationsManager); + _passportImpl = new PassportImpl(communicationsManager); // Subscribe to Passport authentication events - passportImpl.OnAuthEvent += OnPassportAuthEvent; + _passportImpl.OnAuthEvent += OnPassportAuthEvent; } - catch (Exception ex) + catch (Exception) { // Reset everything on error - readySignalReceived = false; + _readySignalReceived = false; Instance = null; - throw ex; + throw; } } @@ -283,50 +281,30 @@ private void Awake() /// public void SetCallTimeout(int ms) { - GetPassportImpl().communicationsManager.SetCallTimeout(ms); + GetPassportImpl().SetCallTimeout(ms); } /// - /// Logs the user into Passport via device code auth. This will open the user's default browser and take them through Passport login. - /// If true, the saved access token or refresh token will be used to log the user in. If this fails, it will not fallback to device code auth. - /// (Optional) The maximum time, in milliseconds, the function is allowed to take before a TimeoutException is thrown. If not set, the function will wait indefinitely. + /// 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. + /// 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. /// /// /// Returns true if login is successful, otherwise false. /// - public async UniTask Login(bool useCachedSession = false, long? timeoutMs = null) - { - return await GetPassportImpl().Login(useCachedSession, timeoutMs); - } - - /// - /// Logs the user into Passport via device code auth and sets up the Immutable X provider. This will open the user's - /// default browser and take them through Passport login. - /// If true, the saved access token or refresh token will be used to connect the user. If this fails, it will not fallback to device code auth. - /// (Optional) The maximum time, in milliseconds, the function is allowed to take before a TimeoutException is thrown. If not set, the function will wait indefinitely. - /// - public async UniTask ConnectImx(bool useCachedSession = false, long? timeoutMs = null) - { - return await GetPassportImpl().ConnectImx(useCachedSession, timeoutMs); - } - - /// - /// Connects the user into Passport via PKCE auth. - /// - public async UniTask LoginPKCE() + public async UniTask Login(bool useCachedSession = false) { - await GetPassportImpl().LoginPKCE(); + return await GetPassportImpl().Login(useCachedSession); } /// - /// Connects the user into Passport via PKCE auth and sets up the Immutable X provider. - /// - /// The user does not need to go through this flow if the saved access token is still valid or - /// the refresh token can be used to get a new access token. + /// 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. + /// 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. /// - public async UniTask ConnectImxPKCE() + public async UniTask ConnectImx(bool useCachedSession = false) { - return await GetPassportImpl().ConnectImxPKCE(); + return await GetPassportImpl().ConnectImx(useCachedSession); } /// @@ -335,14 +313,13 @@ public async UniTask ConnectImxPKCE() /// The wallet address /// /// - public async UniTask GetAddress() + public async UniTask GetAddress() { return await GetPassportImpl().GetAddress(); } /// /// Logs the user out of Passport and removes any stored credentials. - /// Recommended to use when logging in using device auth flow - ConnectImx() /// /// If false, the user will not be logged out of Passport in the browser. The default is true. public async UniTask Logout(bool hardLogout = true) @@ -350,20 +327,10 @@ public async UniTask Logout(bool hardLogout = true) await GetPassportImpl().Logout(hardLogout); } - /// - /// Logs the user out of Passport and removes any stored credentials. - /// Recommended to use when logging in using PKCE flow - ConnectImxPKCE() - /// - /// If false, the user will not be logged out of Passport in the browser. The default is true. - public async UniTask LogoutPKCE(bool hardLogout = true) - { - await GetPassportImpl().LogoutPKCE(hardLogout); - } - /// /// Checks if credentials exist but does not check if they're valid /// - /// True if there are crendentials saved + /// True if there are credentials saved /// /// public UniTask HasCredentialsSaved() @@ -385,7 +352,7 @@ public async UniTask IsRegisteredOffchain() /// /// Registers the user to Immutable X if they are not already registered /// - public async UniTask RegisterOffchain() + public async UniTask RegisterOffchain() { return await GetPassportImpl().RegisterOffchain(); } @@ -396,10 +363,9 @@ public async UniTask RegisterOffchain() /// The email address /// /// - public async UniTask GetEmail() + public async UniTask GetEmail() { - string email = await GetPassportImpl().GetEmail(); - return email; + return await GetPassportImpl().GetEmail(); } /// @@ -408,10 +374,9 @@ public async UniTask GetEmail() /// The Passport ID /// /// - public async UniTask GetPassportId() + public async UniTask GetPassportId() { - string passportId = await GetPassportImpl().GetPassportId(); - return passportId; + return await GetPassportImpl().GetPassportId(); } /// @@ -420,9 +385,9 @@ public async UniTask GetPassportId() /// The access token /// /// - public UniTask GetAccessToken() + public async UniTask GetAccessToken() { - return GetPassportImpl().GetAccessToken(); + return await GetPassportImpl().GetAccessToken(); } /// @@ -431,9 +396,9 @@ public UniTask GetAccessToken() /// The ID token /// /// - public UniTask GetIdToken() + public async UniTask GetIdToken() { - return GetPassportImpl().GetIdToken(); + return await GetPassportImpl().GetIdToken(); } /// @@ -454,10 +419,9 @@ public async UniTask> GetLinkedAddresses() /// The transfer response if successful /// /// - public async UniTask ImxTransfer(UnsignedTransferRequest request) + public async UniTask ImxTransfer(UnsignedTransferRequest request) { - CreateTransferResponseV1 response = await GetPassportImpl().ImxTransfer(request); - return response; + return await GetPassportImpl().ImxTransfer(request); } /// @@ -466,10 +430,9 @@ public async UniTask ImxTransfer(UnsignedTransferReque /// The transfer response if successful /// /// - public async UniTask ImxBatchNftTransfer(NftTransferDetails[] details) + public async UniTask ImxBatchNftTransfer(NftTransferDetails[] details) { - CreateBatchTransferResponse response = await GetPassportImpl().ImxBatchNftTransfer(details); - return response; + return await GetPassportImpl().ImxBatchNftTransfer(details); } /// @@ -487,7 +450,7 @@ public async UniTask ConnectEvm() /// The transaction hash, or the zero hash if the transaction is not yet available. /// /// - public async UniTask ZkEvmSendTransaction(TransactionRequest request) + public async UniTask ZkEvmSendTransaction(TransactionRequest request) { return await GetPassportImpl().ZkEvmSendTransaction(request); } @@ -498,7 +461,7 @@ public async UniTask ZkEvmSendTransaction(TransactionRequest request) /// The receipt of the transaction or null if it is still processing. /// /// - public async UniTask ZkEvmSendTransactionWithConfirmation(TransactionRequest request) + public async UniTask ZkEvmSendTransactionWithConfirmation(TransactionRequest request) { return await GetPassportImpl().ZkEvmSendTransactionWithConfirmation(request); } @@ -509,7 +472,7 @@ public async UniTask ZkEvmSendTransactionWithConfirm /// The receipt of the transaction or null if it is still processing. /// /// - public async UniTask ZkEvmGetTransactionReceipt(string hash) + public async UniTask ZkEvmGetTransactionReceipt(string hash) { return await GetPassportImpl().ZkEvmGetTransactionReceipt(hash); } @@ -522,7 +485,7 @@ public async UniTask ZkEvmGetTransactionReceipt(stri /// The signed payload string. /// /// - public async UniTask ZkEvmSignTypedDataV4(string payload) + public async UniTask ZkEvmSignTypedDataV4(string payload) { return await GetPassportImpl().ZkEvmSignTypedDataV4(payload); } @@ -630,18 +593,18 @@ private static string RedactTokenValues(string message) private PassportImpl GetPassportImpl() { - if (passportImpl != null) + if (_passportImpl != null) { - return passportImpl; + return _passportImpl; } throw new PassportException("Passport not initialised"); } private void OnDeepLinkActivated(string url) { - deeplink = url; + _deeplink = url; - if (passportImpl != null) + if (_passportImpl != null) { GetPassportImpl().OnDeepLinkActivated(url); } @@ -649,10 +612,7 @@ private void OnDeepLinkActivated(string url) private void OnPassportAuthEvent(PassportAuthEvent authEvent) { - if (OnAuthEvent != null) - { - OnAuthEvent.Invoke(authEvent); - } + OnAuthEvent?.Invoke(authEvent); } /// @@ -700,10 +660,10 @@ private void DisposeAll() // Unsubscribe from Passport authentication events // and dispose of the Passport implementation - if (passportImpl != null) + if (_passportImpl != null) { - passportImpl.OnAuthEvent -= OnPassportAuthEvent; - passportImpl = null; + _passportImpl.OnAuthEvent -= OnPassportAuthEvent; + _passportImpl = null; } // Unsubscribe from application quitting event @@ -716,8 +676,8 @@ private void DisposeAll() // Reset static fields Instance = null; - deeplink = null; - readySignalReceived = false; + _deeplink = null; + _readySignalReceived = false; } } } diff --git a/src/Packages/Passport/Tests/Runtime/Scripts/PassportTests.cs b/src/Packages/Passport/Tests/Runtime/Scripts/PassportTests.cs index a7c26e93..85519cd0 100644 --- a/src/Packages/Passport/Tests/Runtime/Scripts/PassportTests.cs +++ b/src/Packages/Passport/Tests/Runtime/Scripts/PassportTests.cs @@ -34,7 +34,6 @@ protected override void Track(string eventName, bool? success = null, Dictionary [TestFixture] public class PassportImplTests { - internal static string DEVICE_CODE = "deviceCode"; internal static string ACCESS_TOKEN = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6Ikp" + "vaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyLCJleHAiOjEyM30.kRqQkJudxgI3koJAp9K4ENp6E2ExFQ5VchogaTWx6Fk"; internal static string ACCESS_TOKEN_KEY = "accessToken"; @@ -48,14 +47,12 @@ public class PassportImplTests internal static string PASSPORT_ID = "email|123457890"; internal static string SIGNATURE = "0xsignature"; internal static string MESSAGE = "message"; - internal static string CODE = "IMX"; internal static string URL = "https://auth.immutable.com/device"; internal static string LOGOUT_URL = "https://auth.immutable.com/logout"; internal static int INTERVAL = 5; - private const string REQUEST_ID = "50"; #pragma warning disable CS8618 - private MockBrowserCommsManager communicationsManager; + private MockBrowserCommunicationsManager communicationsManager; private TestPassportImpl passport; #pragma warning restore CS8618 @@ -65,12 +62,12 @@ public class PassportImplTests [SetUp] public void Init() { - communicationsManager = new MockBrowserCommsManager(); + communicationsManager = new MockBrowserCommunicationsManager(); urlsOpened = new List(); authEvents = new List(); passport = new TestPassportImpl(communicationsManager, urlsOpened); passport.OnAuthEvent += OnPassportAuthEvent; - communicationsManager.responses.Clear(); + communicationsManager.Responses.Clear(); } [TearDown] @@ -85,323 +82,6 @@ private void OnPassportAuthEvent(PassportAuthEvent authEvent) authEvents.Add(authEvent); } - [Test] - public async Task Login_Logout_Success() - { - var deviceConnectResponse = new DeviceConnectResponse - { - success = true, - code = CODE, - deviceCode = DEVICE_CODE, - url = URL, - interval = INTERVAL - }; - communicationsManager.AddMockResponse(deviceConnectResponse); - var confirmCodeResponse = new BrowserResponse - { - success = true - }; - communicationsManager.AddMockResponse(confirmCodeResponse); - var logoutResponse = new StringResponse - { - success = true, - result = LOGOUT_URL - }; - communicationsManager.AddMockResponse(logoutResponse); - - // Login - bool success = await passport.Login(); - Assert.True(success); - - // Logout - await passport.Logout(); - - Assert.AreEqual(2, urlsOpened.Count); - Assert.AreEqual(URL, urlsOpened[0]); - Assert.AreEqual(LOGOUT_URL, urlsOpened[1]); - List expectedEvents = new List{ - PassportAuthEvent.LoggingIn, - PassportAuthEvent.LoginOpeningBrowser, - PassportAuthEvent.PendingBrowserLogin, - PassportAuthEvent.LoginSuccess, - PassportAuthEvent.LoggingOut, - PassportAuthEvent.LogoutSuccess - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task Login_Soft_Logout_Success() - { - var deviceConnectResponse = new DeviceConnectResponse - { - success = true, - code = CODE, - deviceCode = DEVICE_CODE, - url = URL, - interval = INTERVAL - }; - communicationsManager.AddMockResponse(deviceConnectResponse); - var confirmCodeResponse = new BrowserResponse - { - success = true - }; - communicationsManager.AddMockResponse(confirmCodeResponse); - var logoutResponse = new StringResponse - { - success = true, - result = LOGOUT_URL - }; - communicationsManager.AddMockResponse(logoutResponse); - - // Login - bool success = await passport.Login(); - Assert.True(success); - - // Logout - await passport.Logout(hardLogout: false); - - Assert.AreEqual(1, urlsOpened.Count); - Assert.AreEqual(URL, urlsOpened[0]); - List expectedEvents = new List{ - PassportAuthEvent.LoggingIn, - PassportAuthEvent.LoginOpeningBrowser, - PassportAuthEvent.PendingBrowserLogin, - PassportAuthEvent.LoginSuccess, - PassportAuthEvent.LoggingOut, - PassportAuthEvent.LogoutSuccess - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task Login_InitialiseDeviceCodeAuth_Failed() - { - var deviceConnectResponse = new DeviceConnectResponse - { - success = false - }; - communicationsManager.AddMockResponse(deviceConnectResponse); - - PassportException e = null; - try - { - await passport.Login(); - } - catch (PassportException exception) - { - e = exception; - } - - Assert.NotNull(e); - - Assert.AreEqual(0, urlsOpened.Count); - List expectedEvents = new List{ - PassportAuthEvent.LoggingIn, - PassportAuthEvent.LoginFailed - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task Login_InitialiseDeviceCodeAuth_NullResponse_Failed() - { - PassportException e = null; - try - { - await passport.Login(); - } - catch (PassportException exception) - { - e = exception; - } - - Assert.NotNull(e); - - Assert.AreEqual(0, urlsOpened.Count); - List expectedEvents = new List{ - PassportAuthEvent.LoggingIn, - PassportAuthEvent.LoginFailed - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task Login_ConfirmCode_Failed() - { - var deviceConnectResponse = new DeviceConnectResponse - { - success = true, - code = CODE, - deviceCode = DEVICE_CODE, - url = URL - }; - communicationsManager.AddMockResponse(deviceConnectResponse); - var confirmCodeResponse = new BrowserResponse - { - success = false - }; - communicationsManager.AddMockResponse(confirmCodeResponse); - - PassportException e = null; - try - { - await passport.Login(); - } - catch (PassportException exception) - { - e = exception; - } - - Assert.NotNull(e); - - Assert.AreEqual(1, urlsOpened.Count); - Assert.AreEqual(URL, urlsOpened[0]); - List expectedEvents = new List{ - PassportAuthEvent.LoggingIn, - PassportAuthEvent.LoginOpeningBrowser, - PassportAuthEvent.PendingBrowserLogin, - PassportAuthEvent.LoginFailed - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task Login_ConfirmCode_NullResponse_Failed() - { - var deviceConnectResponse = new DeviceConnectResponse - { - success = true, - code = CODE, - deviceCode = DEVICE_CODE, - url = URL - }; - communicationsManager.AddMockResponse(deviceConnectResponse); - - PassportException e = null; - try - { - await passport.Login(); - } - catch (PassportException exception) - { - e = exception; - } - - Assert.NotNull(e); - - Assert.AreEqual(1, urlsOpened.Count); - Assert.AreEqual(URL, urlsOpened[0]); - List expectedEvents = new List{ - PassportAuthEvent.LoggingIn, - PassportAuthEvent.LoginOpeningBrowser, - PassportAuthEvent.PendingBrowserLogin, - PassportAuthEvent.LoginFailed - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task Login_ValidTimeout() - { - var deviceConnectResponse = new DeviceConnectResponse - { - success = true, - code = CODE, - deviceCode = DEVICE_CODE, - url = URL, - interval = INTERVAL - }; - communicationsManager.AddMockResponse(deviceConnectResponse); - var confirmCodeResponse = new BrowserResponse - { - success = true - }; - communicationsManager.AddMockResponse(confirmCodeResponse); - - // Login - bool success = false; - ArgumentException e = null; - try - { - success = await passport.Login(timeoutMs: 6000); - } - catch (ArgumentException exception) - { - e = exception; - } - - Assert.Null(e); - Assert.True(success); - } - - [Test] - public async Task Login_InvalidTimeout() - { - var deviceConnectResponse = new DeviceConnectResponse - { - success = true, - code = CODE, - deviceCode = DEVICE_CODE, - url = URL, - interval = INTERVAL - }; - communicationsManager.AddMockResponse(deviceConnectResponse); - - ArgumentException e = null; - try - { - await passport.Login(timeoutMs: 1); - } - catch (ArgumentException exception) - { - e = exception; - } - - Assert.NotNull(e); - } - - [Test] - public async Task Relogin_Success() - { - var reloginResponse = new BoolResponse - { - success = true, - result = true - }; - communicationsManager.AddMockResponse(reloginResponse); - var logoutResponse = new StringResponse - { - success = true, - result = LOGOUT_URL - }; - communicationsManager.AddMockResponse(logoutResponse); - - // Relogin - bool success = await passport.Login(useCachedSession: true); - Assert.True(success); - - // Logout - await passport.Logout(); - - Assert.AreEqual(1, urlsOpened.Count); - Assert.AreEqual(LOGOUT_URL, urlsOpened[0]); - List expectedEvents = new List{ - PassportAuthEvent.ReloggingIn, - PassportAuthEvent.ReloginSuccess, - PassportAuthEvent.LoggingOut, - PassportAuthEvent.LogoutSuccess - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - [Test] public async Task Relogin_Failed() { @@ -426,7 +106,7 @@ public async Task Relogin_Failed() [Test] public async Task Relogin_CallFailed() { - communicationsManager.throwExceptionOnCall = true; + communicationsManager.ThrowExceptionOnCall = true; bool success = await passport.Login(useCachedSession: true); Assert.False(success); @@ -455,416 +135,6 @@ public async Task Relogin_NullResponse_Failed() Assert.AreEqual(expectedEvents, authEvents); } - [Test] - public async Task ConnectImx_Logout_Success() - { - communicationsManager.responses.Enqueue(JsonUtility.ToJson(new StringResponse - { - success = true - })); - communicationsManager.responses.Enqueue(JsonUtility.ToJson(new StringResponse - { - success = true - })); - var reconnectResponse = new BoolResponse - { - success = false - }; - communicationsManager.AddMockResponse(reconnectResponse); - var deviceConnectResponse = new DeviceConnectResponse - { - success = true, - code = CODE, - deviceCode = DEVICE_CODE, - url = URL, - interval = INTERVAL - }; - communicationsManager.AddMockResponse(deviceConnectResponse); - var confirmCodeResponse = new BrowserResponse - { - success = true - }; - communicationsManager.AddMockResponse(confirmCodeResponse); - var logoutResponse = new StringResponse - { - success = true, - result = LOGOUT_URL - }; - communicationsManager.AddMockResponse(logoutResponse); - - // Connect - bool success = await passport.ConnectImx(); - Assert.True(success); - - // Logout - await passport.Logout(); - - Assert.AreEqual(2, urlsOpened.Count); - Assert.AreEqual(URL, urlsOpened[0]); - Assert.AreEqual(LOGOUT_URL, urlsOpened[1]); - List expectedEvents = new List{ - PassportAuthEvent.CheckingForSavedCredentials, - PassportAuthEvent.CheckForSavedCredentialsSuccess, - PassportAuthEvent.Reconnecting, - PassportAuthEvent.ReconnectFailed, - PassportAuthEvent.ConnectingImx, - PassportAuthEvent.ConnectImxOpeningBrowser, - PassportAuthEvent.PendingBrowserLoginAndProviderSetup, - PassportAuthEvent.ConnectImxSuccess, - PassportAuthEvent.LoggingOut, - PassportAuthEvent.LogoutSuccess - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task ConnectImx_InitialiseDeviceCodeAuth_Failed() - { - communicationsManager.responses.Enqueue(JsonUtility.ToJson(new StringResponse - { - success = true - })); - communicationsManager.responses.Enqueue(JsonUtility.ToJson(new StringResponse - { - success = true - })); - var reconnectResponse = new BoolResponse - { - success = false - }; - communicationsManager.AddMockResponse(reconnectResponse); - var deviceConnectResponse = new DeviceConnectResponse - { - success = false - }; - communicationsManager.AddMockResponse(deviceConnectResponse); - - PassportException e = null; - try - { - await passport.ConnectImx(); - } - catch (PassportException exception) - { - e = exception; - } - - Assert.NotNull(e); - - Assert.AreEqual(0, urlsOpened.Count); - List expectedEvents = new List{ - PassportAuthEvent.CheckingForSavedCredentials, - PassportAuthEvent.CheckForSavedCredentialsSuccess, - PassportAuthEvent.Reconnecting, - PassportAuthEvent.ReconnectFailed, - PassportAuthEvent.ConnectingImx, - PassportAuthEvent.ConnectImxFailed - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task ConnectImx_InitialiseDeviceCodeAuth_NullResponse_Failed() - { - communicationsManager.responses.Enqueue(JsonUtility.ToJson(new StringResponse - { - success = true - })); - communicationsManager.responses.Enqueue(JsonUtility.ToJson(new StringResponse - { - success = true - })); - var reconnectResponse = new BoolResponse - { - success = false - }; - communicationsManager.AddMockResponse(reconnectResponse); - - PassportException e = null; - try - { - await passport.ConnectImx(); - } - catch (PassportException exception) - { - e = exception; - } - - Assert.NotNull(e); - - Assert.AreEqual(0, urlsOpened.Count); - List expectedEvents = new List{ - PassportAuthEvent.CheckingForSavedCredentials, - PassportAuthEvent.CheckForSavedCredentialsSuccess, - PassportAuthEvent.Reconnecting, - PassportAuthEvent.ReconnectFailed, - PassportAuthEvent.ConnectingImx, - PassportAuthEvent.ConnectImxFailed - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task ConnectImx_ConfirmCode_Failed() - { - communicationsManager.AddMockResponse(new StringResponse - { - success = true - }); - communicationsManager.AddMockResponse(new StringResponse - { - success = true - }); - var reconnectResponse = new BoolResponse - { - success = false - }; - communicationsManager.AddMockResponse(reconnectResponse); - var deviceConnectResponse = new DeviceConnectResponse - { - success = true, - code = CODE, - deviceCode = DEVICE_CODE, - url = URL, - interval = INTERVAL - }; - communicationsManager.AddMockResponse(deviceConnectResponse); - var confirmCodeResponse = new BrowserResponse - { - success = false - }; - communicationsManager.AddMockResponse(confirmCodeResponse); - - PassportException e = null; - try - { - await passport.ConnectImx(); - } - catch (PassportException exception) - { - e = exception; - } - - Assert.NotNull(e); - - Assert.AreEqual(1, urlsOpened.Count); - Assert.AreEqual(URL, urlsOpened[0]); - List expectedEvents = new List{ - PassportAuthEvent.CheckingForSavedCredentials, - PassportAuthEvent.CheckForSavedCredentialsSuccess, - PassportAuthEvent.Reconnecting, - PassportAuthEvent.ReconnectFailed, - PassportAuthEvent.ConnectingImx, - PassportAuthEvent.ConnectImxOpeningBrowser, - PassportAuthEvent.PendingBrowserLoginAndProviderSetup, - PassportAuthEvent.ConnectImxFailed - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task ConnectImx_ConfirmCode_NullResponse_Failed() - { - communicationsManager.responses.Enqueue(JsonUtility.ToJson(new StringResponse - { - success = true - })); - communicationsManager.responses.Enqueue(JsonUtility.ToJson(new StringResponse - { - success = true - })); - var reconnectResponse = new BoolResponse - { - success = false - }; - communicationsManager.AddMockResponse(reconnectResponse); - var deviceConnectResponse = new DeviceConnectResponse - { - success = true, - code = CODE, - deviceCode = DEVICE_CODE, - url = URL, - interval = INTERVAL - }; - communicationsManager.AddMockResponse(deviceConnectResponse); - - PassportException e = null; - try - { - await passport.ConnectImx(); - } - catch (PassportException exception) - { - e = exception; - } - - Assert.NotNull(e); - - Assert.AreEqual(1, urlsOpened.Count); - Assert.AreEqual(URL, urlsOpened[0]); - List expectedEvents = new List{ - PassportAuthEvent.CheckingForSavedCredentials, - PassportAuthEvent.CheckForSavedCredentialsSuccess, - PassportAuthEvent.Reconnecting, - PassportAuthEvent.ReconnectFailed, - PassportAuthEvent.ConnectingImx, - PassportAuthEvent.ConnectImxOpeningBrowser, - PassportAuthEvent.PendingBrowserLoginAndProviderSetup, - PassportAuthEvent.ConnectImxFailed - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task ConnectImx_HasCredentialsSaved_CannotReconnect_Logout_Success() - { - communicationsManager.responses.Enqueue(JsonUtility.ToJson(new StringResponse - { - success = true, - result = ACCESS_TOKEN - })); - communicationsManager.responses.Enqueue(JsonUtility.ToJson(new StringResponse - { - success = true, - result = ID_TOKEN - })); - var reconnectResponse = new BoolResponse - { - success = false - }; - communicationsManager.AddMockResponse(reconnectResponse); - var deviceConnectResponse = new DeviceConnectResponse - { - success = true, - code = CODE, - deviceCode = DEVICE_CODE, - url = URL, - interval = INTERVAL - }; - communicationsManager.AddMockResponse(deviceConnectResponse); - var confirmCodeResponse = new BrowserResponse - { - success = true - }; - communicationsManager.AddMockResponse(confirmCodeResponse); - var logoutResponse = new StringResponse - { - success = true, - result = LOGOUT_URL - }; - communicationsManager.AddMockResponse(logoutResponse); - - // Connect - bool success = await passport.ConnectImx(); - Assert.True(success); - - // Logout - await passport.Logout(); - - Assert.AreEqual(2, urlsOpened.Count); - Assert.AreEqual(URL, urlsOpened[0]); - Assert.AreEqual(LOGOUT_URL, urlsOpened[1]); - List expectedEvents = new List{ - PassportAuthEvent.CheckingForSavedCredentials, - PassportAuthEvent.CheckForSavedCredentialsSuccess, - PassportAuthEvent.Reconnecting, - PassportAuthEvent.ReconnectFailed, - PassportAuthEvent.ConnectingImx, - PassportAuthEvent.ConnectImxOpeningBrowser, - PassportAuthEvent.PendingBrowserLoginAndProviderSetup, - PassportAuthEvent.ConnectImxSuccess, - PassportAuthEvent.LoggingOut, - PassportAuthEvent.LogoutSuccess - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task ConnectImx_HasCredentialsSaved_Reconnect_Logout_Success() - { - communicationsManager.responses.Enqueue(JsonUtility.ToJson(new StringResponse - { - success = true, - result = ACCESS_TOKEN - })); - communicationsManager.responses.Enqueue(JsonUtility.ToJson(new StringResponse - { - success = true, - result = ID_TOKEN - })); - var reconnectResponse = new BoolResponse - { - success = true - }; - communicationsManager.AddMockResponse(reconnectResponse); - var logoutResponse = new StringResponse - { - success = true, - result = LOGOUT_URL - }; - communicationsManager.AddMockResponse(logoutResponse); - - // Login - bool success = await passport.ConnectImx(); - Assert.True(success); - - // Logout - await passport.Logout(); - - Assert.AreEqual(1, urlsOpened.Count); - Assert.AreEqual(LOGOUT_URL, urlsOpened[0]); - List expectedEvents = new List{ - PassportAuthEvent.CheckingForSavedCredentials, - PassportAuthEvent.CheckForSavedCredentialsSuccess, - PassportAuthEvent.Reconnecting, - PassportAuthEvent.ReconnectSuccess, - PassportAuthEvent.LoggingOut, - PassportAuthEvent.LogoutSuccess - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task Reconnect_Success() - { - var reconnectResponse = new BoolResponse - { - success = true - }; - communicationsManager.AddMockResponse(reconnectResponse); - var logoutResponse = new StringResponse - { - success = true, - result = LOGOUT_URL - }; - communicationsManager.AddMockResponse(logoutResponse); - - // Reconnect - bool success = await passport.ConnectImx(useCachedSession: true); - Assert.True(success); - - // Logout - await passport.Logout(); - - Assert.AreEqual(1, urlsOpened.Count); - Assert.AreEqual(LOGOUT_URL, urlsOpened[0]); - List expectedEvents = new List{ - PassportAuthEvent.Reconnecting, - PassportAuthEvent.ReconnectSuccess, - PassportAuthEvent.LoggingOut, - PassportAuthEvent.LogoutSuccess - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - [Test] public async Task Reconnect_Failed() { @@ -874,7 +144,7 @@ public async Task Reconnect_Failed() }; communicationsManager.AddMockResponse(reconnectResponse); - bool success = await passport.ConnectImx(useCachedSession: true); + var success = await passport.ConnectImx(useCachedSession: true); Assert.False(success); Assert.AreEqual(0, urlsOpened.Count); @@ -889,7 +159,7 @@ public async Task Reconnect_Failed() [Test] public async Task Reconnect_CallFailed() { - communicationsManager.throwExceptionOnCall = true; + communicationsManager.ThrowExceptionOnCall = true; bool success = await passport.ConnectImx(useCachedSession: true); Assert.False(success); @@ -931,14 +201,14 @@ public async Task GetAddress_Success() var address = await passport.GetAddress(); Assert.AreEqual(ADDRESS, address); - Assert.AreEqual(PassportFunction.IMX.GET_ADDRESS, communicationsManager.fxName); - Assert.True(String.IsNullOrEmpty(communicationsManager.data)); + Assert.AreEqual(PassportFunction.IMX.GET_ADDRESS, communicationsManager.FxName); + Assert.True(String.IsNullOrEmpty(communicationsManager.Data)); } [Test] public async Task GetAddress_Failed() { - communicationsManager.throwExceptionOnCall = true; + communicationsManager.ThrowExceptionOnCall = true; PassportException e = null; try @@ -966,14 +236,14 @@ public async Task GetEmail_Success() var email = await passport.GetEmail(); Assert.AreEqual(EMAIL, email); - Assert.AreEqual(PassportFunction.GET_EMAIL, communicationsManager.fxName); - Assert.True(String.IsNullOrEmpty(communicationsManager.data)); + Assert.AreEqual(PassportFunction.GET_EMAIL, communicationsManager.FxName); + Assert.True(String.IsNullOrEmpty(communicationsManager.Data)); } [Test] public async Task GetEmail_Failed() { - communicationsManager.throwExceptionOnCall = true; + communicationsManager.ThrowExceptionOnCall = true; PassportException e = null; try @@ -1001,14 +271,14 @@ public async Task GetPassportId_Success() var passportId = await passport.GetPassportId(); Assert.AreEqual(PASSPORT_ID, passportId); - Assert.AreEqual(PassportFunction.GET_PASSPORT_ID, communicationsManager.fxName); - Assert.True(String.IsNullOrEmpty(communicationsManager.data)); + Assert.AreEqual(PassportFunction.GET_PASSPORT_ID, communicationsManager.FxName); + Assert.True(String.IsNullOrEmpty(communicationsManager.Data)); } [Test] public async Task GetPassportId_Failed() { - communicationsManager.throwExceptionOnCall = true; + communicationsManager.ThrowExceptionOnCall = true; PassportException e = null; try @@ -1023,100 +293,6 @@ public async Task GetPassportId_Failed() Assert.NotNull(e); } - [Test] - public async Task Logout_Success() - { - var response = new StringResponse - { - success = true, - result = URL - }; - communicationsManager.AddMockResponse(response); - - PassportException e = null; - try - { - await passport.Logout(); - } - catch (PassportException ex) - { - e = ex; - } - - Assert.Null(e); - - Assert.AreEqual(1, urlsOpened.Count); - List expectedEvents = new List{ - PassportAuthEvent.LoggingOut, - PassportAuthEvent.LogoutSuccess - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task Logout_FailedGetLogoutUrl() - { - var response = new StringResponse - { - success = false - }; - communicationsManager.AddMockResponse(response); - - PassportException e = null; - try - { - await passport.Logout(); - } - catch (PassportException ex) - { - e = ex; - } - - LogAssert.Expect(LogType.Error, "[Immutable] [Passport Implementation] Failed to log out: Response is invalid!"); - Assert.NotNull(e); - - Assert.AreEqual(0, urlsOpened.Count); - List expectedEvents = new List{ - PassportAuthEvent.LoggingOut, - PassportAuthEvent.LogoutFailed - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - - [Test] - public async Task Logout_EmptyGetLogoutUrl() - { - var response = new StringResponse - { - success = true, - result = "" - }; - communicationsManager.AddMockResponse(response); - - PassportException e = null; - try - { - await passport.Logout(); - } - catch (PassportException ex) - { - e = ex; - } - - LogAssert.Expect(LogType.Error, "[Immutable] [Passport Implementation] Failed to log out: Failed to get logout URL"); - Assert.NotNull(e); - - Assert.AreEqual(0, urlsOpened.Count); - List expectedEvents = new List{ - PassportAuthEvent.LoggingOut, - PassportAuthEvent.LogoutFailed - }; - Assert.AreEqual(expectedEvents.Count, authEvents.Count); - Assert.AreEqual(expectedEvents, authEvents); - } - [Test] public async Task GetLinkedAddresses_Success() { @@ -1138,7 +314,7 @@ public async Task GetLinkedAddresses_Success() [Test] public async Task GetLinkedAddresses_Failed() { - communicationsManager.throwExceptionOnCall = true; + communicationsManager.ThrowExceptionOnCall = true; PassportException e = null; try @@ -1185,48 +361,43 @@ public async Task GetLinkedAddresses_EmptyResponse() } } - internal class MockBrowserCommsManager : IBrowserCommunicationsManager + internal class MockBrowserCommunicationsManager : IBrowserCommunicationsManager { - public Queue responses = new Queue(); - public bool throwExceptionOnCall = false; - public string fxName = ""; - public string data = ""; - public event OnUnityPostMessageDelegate OnAuthPostMessage; - public event OnUnityPostMessageErrorDelegate OnPostMessageError; + public Queue Responses = new(); + public bool ThrowExceptionOnCall; + public string FxName = ""; + public string? Data = ""; + public event OnUnityPostMessageDelegate? OnAuthPostMessage; + public event OnUnityPostMessageErrorDelegate? OnPostMessageError; public void AddMockResponse(object response) { - responses.Enqueue(JsonUtility.ToJson(response)); + Responses.Enqueue(JsonUtility.ToJson(response)); } - public UniTask Call(string fxName, string data = null, bool ignoreTimeout = false, Nullable timeoutMs = null) + public UniTask Call(string fxName, string? data = null, bool ignoreTimeout = false, long? timeoutMs = null) { - if (throwExceptionOnCall) + if (ThrowExceptionOnCall) { Debug.Log("Error on call"); throw new PassportException("Error on call!"); } - else + + FxName = fxName; + Data = data; + var result = Responses.Count > 0 ? Responses.Dequeue() : ""; + var response = result.OptDeserializeObject(); + if (response == null || response?.success == false || !string.IsNullOrEmpty(response?.error)) { - this.fxName = fxName; - this.data = data; - string result = responses.Count > 0 ? responses.Dequeue() : ""; - BrowserResponse response = result.OptDeserializeObject(); - if (response == null || response?.success == false || !String.IsNullOrEmpty(response?.error)) - { - Debug.Log("No response"); - throw new PassportException("Response is invalid!"); - } - else - { - return UniTask.FromResult(result); - } + Debug.Log("No response"); + throw new PassportException("Response is invalid!"); } + + return UniTask.FromResult(result); } public void LaunchAuthURL(string url, string redirectUri) { - throw new NotImplementedException(); } public void SetCallTimeout(int ms) From 86e8c4bbbc98d51fbf2369708f8a208ef3c109be Mon Sep 17 00:00:00 2001 From: Natalie Bunduwongse Date: Fri, 13 Jun 2025 11:00:02 +1200 Subject: [PATCH 2/8] chore: disable linter for samples folder --- .github/workflows/linter.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/linter.yml b/.github/workflows/linter.yml index f132b399..ea645b93 100644 --- a/.github/workflows/linter.yml +++ b/.github/workflows/linter.yml @@ -57,7 +57,7 @@ jobs: VALIDATE_ALL_CODEBASE: true DEFAULT_BRANCH: main GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - FILTER_REGEX_EXCLUDE: (.*src/Packages/Passport/Runtime/ThirdParty/.*|.*src/Packages/Passport/Runtime/Resources/.*|.*Plugins/.*|.*src/Packages/Passport/Runtime/Assets/ImmutableAndroid.androidlib/.*|.*src/Packages/Orderbook|.*src/Packages/ZkEvmApi/.*|.*sample|.*src/Packages/Passport/WebGLTemplates~|.*.github/workflows) + FILTER_REGEX_EXCLUDE: (.*src/Packages/Passport/Runtime/ThirdParty/.*|.*src/Packages/Passport/Runtime/Resources/.*|.*Plugins/.*|.*src/Packages/Passport/Runtime/Assets/ImmutableAndroid.androidlib/.*|.*src/Packages/Orderbook|.*src/Packages/ZkEvmApi/.*|.*sample|.*src/Packages/Passport/WebGLTemplates~|.*.github/workflows|.*src/Packages/Passport/Samples~) VALIDATE_MARKDOWN: false VALIDATE_GITLEAKS: false VALIDATE_JSCPD: false From ddbff678bc1a97acf1afcdeaa12fc1d0f079bf54 Mon Sep 17 00:00:00 2001 From: Natalie Bunduwongse Date: Tue, 17 Jun 2025 10:46:09 +1200 Subject: [PATCH 3/8] test: mac pkce ui test --- .gitignore | 4 +- Plugins/Mac/Sources/ImmutableWebView.mm | 2 +- Plugins/Mac/install.sh | 1 - sample/Assets/Editor/MacBuilder.cs | 17 +- sample/Assets/Editor/MobileBuilder.cs | 2 +- sample/Assets/Editor/WindowsBuilder.cs | 2 +- .../Scenes/Passport/Initialisation.unity | 6 +- .../Scripts/Passport/Login/LoginScript.cs | 4 +- sample/ProjectSettings/ProjectSettings.asset | 5 +- sample/Tests/test/test_mac.py | 157 ++++++++++-------- .../Runtime/Scripts/Private/PassportImpl.cs | 6 +- .../Gree/Assets/Plugins/WebViewObject.cs | 2 +- 12 files changed, 120 insertions(+), 88 deletions(-) diff --git a/.gitignore b/.gitignore index efc4daa6..6aaa93d8 100644 --- a/.gitignore +++ b/.gitignore @@ -107,4 +107,6 @@ sample/Assets/Vuplex* __pycache__/ *.pyc -.pytest_cache/ \ No newline at end of file +.pytest_cache/ + +xcuserdata/ \ No newline at end of file diff --git a/Plugins/Mac/Sources/ImmutableWebView.mm b/Plugins/Mac/Sources/ImmutableWebView.mm index c9c39e0c..688b1815 100644 --- a/Plugins/Mac/Sources/ImmutableWebView.mm +++ b/Plugins/Mac/Sources/ImmutableWebView.mm @@ -424,5 +424,5 @@ void _CImmutableWebViewPlugin_LaunchAuthURL(void *instance, const char *url, con if (instance == NULL) return; CWebViewPlugin *webViewPlugin = (__bridge CWebViewPlugin *)instance; - [webViewPlugin launchAuthURL:url redirectUri: redirectUri]; + [webViewPlugin launchAuthURL:url redirectUri:redirectUri]; } diff --git a/Plugins/Mac/install.sh b/Plugins/Mac/install.sh index eb5e05ce..f7c8fe08 100755 --- a/Plugins/Mac/install.sh +++ b/Plugins/Mac/install.sh @@ -6,4 +6,3 @@ mkdir -p $DSTDIR cp -r DerivedData/ImmutableWebView.bundle $DSTDIR rm -rf DerivedData -cp *.bundle.meta $DSTDIR diff --git a/sample/Assets/Editor/MacBuilder.cs b/sample/Assets/Editor/MacBuilder.cs index 76575273..c750a419 100644 --- a/sample/Assets/Editor/MacBuilder.cs +++ b/sample/Assets/Editor/MacBuilder.cs @@ -38,6 +38,12 @@ private static void BuildPlayer(string defaultBuildPath, BuildOptions buildOptio { // Clean up AltTester settings after build AltBuilder.RemoveAltTesterFromScriptingDefineSymbols(BuildTargetGroup.Standalone); + + // Clean up custom e2e testing define + var defineSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone); + defineSymbols = defineSymbols.Replace("IMMUTABLE_E2E_TESTING;", "").Replace(";IMMUTABLE_E2E_TESTING", "").Replace("IMMUTABLE_E2E_TESTING", ""); + PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone, defineSymbols); + RemoveAltFromScene(buildPlayerOptions.scenes[0]); } } @@ -66,7 +72,7 @@ private static BuildPlayerOptions CreateBuildPlayerOptions(string buildPath, Bui { scenes = new[] { - "Assets/Scenes/Passport/SelectAuthMethod.unity", + "Assets/Scenes/Passport/Initialisation.unity", "Assets/Scenes/Passport/UnauthenticatedScene.unity", "Assets/Scenes/Passport/AuthenticatedScene.unity", "Assets/Scenes/Passport/ZkEvm/ZkEvmGetBalance.unity", @@ -85,6 +91,15 @@ private static BuildPlayerOptions CreateBuildPlayerOptions(string buildPath, Bui private static void SetupAltTester(BuildPlayerOptions buildPlayerOptions) { AltBuilder.AddAltTesterInScriptingDefineSymbolsGroup(BuildTargetGroup.Standalone); + + // Add custom define for e2e testing to enable default browser behavior + var defineSymbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone); + if (!defineSymbols.Contains("IMMUTABLE_E2E_TESTING")) + { + defineSymbols += ";IMMUTABLE_E2E_TESTING"; + PlayerSettings.SetScriptingDefineSymbolsForGroup(BuildTargetGroup.Standalone, defineSymbols); + } + AltBuilder.CreateJsonFileForInputMappingOfAxis(); var instrumentationSettings = new AltInstrumentationSettings(); diff --git a/sample/Assets/Editor/MobileBuilder.cs b/sample/Assets/Editor/MobileBuilder.cs index 40a52185..df22207a 100644 --- a/sample/Assets/Editor/MobileBuilder.cs +++ b/sample/Assets/Editor/MobileBuilder.cs @@ -117,7 +117,7 @@ private static BuildPlayerOptions CreateBuildPlayerOptions(string buildPath, Bui { scenes = new[] { - "Assets/Scenes/Passport/SelectAuthMethod.unity", + "Assets/Scenes/Passport/Initialisation.unity", "Assets/Scenes/Passport/UnauthenticatedScene.unity", "Assets/Scenes/Passport/AuthenticatedScene.unity", "Assets/Scenes/Passport/ZkEvm/ZkEvmGetBalance.unity", diff --git a/sample/Assets/Editor/WindowsBuilder.cs b/sample/Assets/Editor/WindowsBuilder.cs index 1574af99..1cac2248 100644 --- a/sample/Assets/Editor/WindowsBuilder.cs +++ b/sample/Assets/Editor/WindowsBuilder.cs @@ -66,7 +66,7 @@ private static BuildPlayerOptions CreateBuildPlayerOptions(string buildPath, Bui { scenes = new[] { - "Assets/Scenes/Passport/SelectAuthMethod.unity", + "Assets/Scenes/Passport/Initialisation.unity", "Assets/Scenes/Passport/UnauthenticatedScene.unity", "Assets/Scenes/Passport/AuthenticatedScene.unity", "Assets/Scenes/Passport/ZkEvm/ZkEvmGetBalance.unity", diff --git a/sample/Assets/Scenes/Passport/Initialisation.unity b/sample/Assets/Scenes/Passport/Initialisation.unity index 154b4ed7..998b81f0 100644 --- a/sample/Assets/Scenes/Passport/Initialisation.unity +++ b/sample/Assets/Scenes/Passport/Initialisation.unity @@ -1128,7 +1128,7 @@ MonoBehaviour: m_TargetGraphic: {fileID: 167431872} m_HandleRect: {fileID: 167431871} m_Direction: 2 - m_Value: 1 + m_Value: 0 m_Size: 1 m_NumberOfSteps: 0 m_OnValueChanged: @@ -1398,8 +1398,8 @@ RectTransform: m_LocalEulerAnglesHint: {x: 0, y: 0, z: 0} m_AnchorMin: {x: 0, y: 0} m_AnchorMax: {x: 0, y: 0} - m_AnchoredPosition: {x: 1108.9248, y: 0} - m_SizeDelta: {x: 2177.8496, y: 0} + m_AnchoredPosition: {x: 1801.0891, y: 0} + m_SizeDelta: {x: 3562.1782, y: 0} m_Pivot: {x: 0.5, y: 0.5} --- !u!114 &1661390145 MonoBehaviour: diff --git a/sample/Assets/Scripts/Passport/Login/LoginScript.cs b/sample/Assets/Scripts/Passport/Login/LoginScript.cs index e0d75e70..f14b53a8 100644 --- a/sample/Assets/Scripts/Passport/Login/LoginScript.cs +++ b/sample/Assets/Scripts/Passport/Login/LoginScript.cs @@ -33,9 +33,9 @@ public async void Login() await Passport.Login(); SceneManager.LoadScene("AuthenticatedScene"); } - catch (OperationCanceledException) + catch (OperationCanceledException ex) { - ShowOutput("Failed to login: cancelled"); + ShowOutput($"Failed to login: cancelled {ex.Message}\\n{ex.StackTrace}"); } catch (Exception ex) { diff --git a/sample/ProjectSettings/ProjectSettings.asset b/sample/ProjectSettings/ProjectSettings.asset index d381c981..5d4bf39d 100644 --- a/sample/ProjectSettings/ProjectSettings.asset +++ b/sample/ProjectSettings/ProjectSettings.asset @@ -76,7 +76,7 @@ PlayerSettings: androidFullscreenMode: 1 defaultIsNativeResolution: 1 macRetinaSupport: 0 - runInBackground: 0 + runInBackground: 1 captureSingleScreen: 0 muteOtherAudioSources: 0 Prepare IOS For Recording: 0 @@ -222,7 +222,8 @@ PlayerSettings: iOSDeviceRequirements: [] iOSURLSchemes: - immutablerunner - macOSURLSchemes: [] + macOSURLSchemes: + - immutablerunner iOSBackgroundModes: 0 iOSMetalForceHardShadows: 0 metalEditorSupport: 1 diff --git a/sample/Tests/test/test_mac.py b/sample/Tests/test/test_mac.py index a2a4e2bf..58d83f4e 100644 --- a/sample/Tests/test/test_mac.py +++ b/sample/Tests/test/test_mac.py @@ -1,5 +1,7 @@ import sys import time +import os +import subprocess from pathlib import Path from selenium import webdriver @@ -21,44 +23,81 @@ class MacTest(UnityTest): altdriver = None - seleniumdriver = None @classmethod def setUpClass(cls): open_sample_app() cls.altdriver = AltDriver() + cls.stop_browser() @classmethod def tearDownClass(cls): stop_sample_app() cls.altdriver.stop() + cls.stop_browser() @classmethod - def setupChrome(cls): - print("Connect to Chrome") - chrome_options = Options() - chrome_options.add_argument('--remote-debugging-port=9222') + def launch_browser(cls): + print("Starting Browser...") + browser_paths = [ + "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser" + ] + + browser_path = None + for path in browser_paths: + if os.path.exists(path): + browser_path = path + break + + if not browser_path: + print("Brave executable not found.") + exit(1) + + subprocess.Popen([ + browser_path, + "--remote-debugging-port=9222" + ]) - # Initialise Chrome driver - cls.seleniumdriver = webdriver.Chrome(options=chrome_options) + time.sleep(5) - print("Open a window on Chrome") - cls.seleniumdriver.current_window_handle + @classmethod + def stop_browser(cls): + print("Stopping Brave...") + try: + # First try graceful shutdown using AppleScript + subprocess.run([ + "osascript", "-e", + 'tell application "Brave Browser" to quit' + ], check=False, capture_output=True) + time.sleep(2) + + # Check if still running, then force kill + result = subprocess.run(["pgrep", "-f", "Brave Browser"], + capture_output=True, text=True) + if result.returncode == 0: + # Still running, force kill + subprocess.run(["pkill", "-f", "Brave Browser"], + check=False, capture_output=True) + + print("All Brave processes have been closed.") + except Exception as e: + print("Brave might not be running.") + + time.sleep(3) + print("Stopped Brave") @classmethod def login(cls): - print("Waiting for new window...") - WebDriverWait(cls.seleniumdriver, 30).until(EC.number_of_windows_to_be(2)) + print("Connect to Chrome") + # Set up Chrome options to connect to the existing Chrome instance + chrome_options = Options() + chrome_options.add_experimental_option("debuggerAddress", "localhost:9222") + # Connect to the existing Chrome instance + cls.seleniumdriver = webdriver.Chrome(options=chrome_options) - # Switch to the new window - all_windows = cls.seleniumdriver.window_handles - new_window = [window for window in all_windows if window != cls.seleniumdriver.current_window_handle][0] - cls.seleniumdriver.switch_to.window(new_window) - print("Switched to new window") + print("Open a window on Chrome") - ## Device confirmation - contine_button = WebDriverWait(cls.seleniumdriver, 60).until(EC.element_to_be_clickable((SeleniumBy.XPATH, "//button[span[text()='Continue']]"))) - contine_button.click() + wait = WebDriverWait(cls.seleniumdriver, 60) # Wait for email input and enter email email_field = WebDriverWait(cls.seleniumdriver, 60).until(EC.presence_of_element_located((SeleniumBy.ID, ':r1:'))) @@ -83,16 +122,23 @@ def login(cls): print("Entering OTP...") otp_field.send_keys(code) - # Wait for success page and confirm - success = WebDriverWait(cls.seleniumdriver, 60).until(EC.presence_of_element_located((SeleniumBy.CSS_SELECTOR, 'h1[data-testid="device_success_title"]'))) - print("Connected to Passport!") - + time.sleep(5) + cls.seleniumdriver.quit() - def test_1_device_code_login(self): - # Select use device code auth - self.altdriver.find_object(By.NAME, "DeviceCodeAuth").tap() + @classmethod + def logout(cls): + print("Logging out...") + cls.launch_browser() + bring_sample_app_to_foreground() + cls.altdriver.find_object(By.NAME, "LogoutBtn").tap() + time.sleep(5) + cls.altdriver.wait_for_current_scene_to_be("UnauthenticatedScene") + time.sleep(2) + cls.stop_browser() + print("Logged out") + def test_1_login(self): # Wait for unauthenticated screen self.altdriver.wait_for_current_scene_to_be("UnauthenticatedScene") @@ -104,15 +150,16 @@ def test_1_device_code_login(self): # Login print("Logging in...") - self.setupChrome() + self.launch_browser() bring_sample_app_to_foreground() login_button.tap() self.login() - bring_sample_app_to_foreground() # Wait for authenticated screen self.altdriver.wait_for_current_scene_to_be("AuthenticatedScene") print("Logged in") + + self.stop_browser() return except Exception as err: if attempt == 0: @@ -127,16 +174,7 @@ def test_1_device_code_login(self): print("Re-logged in") # Logout - print("Logging out...") - self.setupChrome() - bring_sample_app_to_foreground() - self.altdriver.find_object(By.NAME, "LogoutBtn").tap() - time.sleep(5) - bring_sample_app_to_foreground() - - # Wait for unauthenticated screen - self.altdriver.wait_for_current_scene_to_be("UnauthenticatedScene") - self.seleniumdriver.quit() + self.logout() print("Logged out and successfully reset app") time.sleep(5) @@ -155,18 +193,16 @@ def test_4_imx_functions(self): def test_5_zkevm_functions(self): self.test_3_zkevm_functions() - def test_6_device_code_relogin(self): + def test_6_relogin(self): # Close and reopen app stop_sample_app() open_sample_app() # Restart AltTester self.altdriver.stop() - self.altdriver = AltDriver() + self.__class__.altdriver = AltDriver() time.sleep(5) - # Select use device code auth - self.altdriver.find_object(By.NAME, "DeviceCodeAuth").tap() # Wait for unauthenticated screen self.altdriver.wait_for_current_scene_to_be("UnauthenticatedScene") @@ -189,18 +225,16 @@ def test_6_device_code_relogin(self): self.altdriver.stop() - def test_7_reconnect_device_code_connect_imx(self): + def test_7_reconnect_connect_imx(self): # Close and reopen app stop_sample_app() open_sample_app() # Restart AltTester self.altdriver.stop() - self.altdriver = AltDriver() + self.__class__.altdriver = AltDriver() time.sleep(5) - # Select use device code auth - self.altdriver.find_object(By.NAME, "DeviceCodeAuth").tap() # Wait for unauthenticated screen self.altdriver.wait_for_current_scene_to_be("UnauthenticatedScene") @@ -222,28 +256,19 @@ def test_7_reconnect_device_code_connect_imx(self): self.assertEqual(TestConfig.WALLET_ADDRESS, output.get_text()) # Logout - print("Logging out...") - self.setupChrome() - bring_sample_app_to_foreground() - self.altdriver.find_object(By.NAME, "LogoutBtn").tap() - time.sleep(5) - bring_sample_app_to_foreground() - - # Wait for authenticated screen - self.altdriver.wait_for_current_scene_to_be("UnauthenticatedScene") - self.seleniumdriver.quit() - print("Logged out") + self.logout() # Connect IMX + time.sleep(5) print("Logging in and connecting to IMX...") - self.setupChrome() + self.launch_browser() bring_sample_app_to_foreground() self.altdriver.wait_for_object(By.NAME, "ConnectBtn").tap() self.login() - bring_sample_app_to_foreground() - # Wait for authenticated screen self.altdriver.wait_for_current_scene_to_be("AuthenticatedScene") + + self.stop_browser() print("Logged in and connected to IMX") # Get access token @@ -256,14 +281,4 @@ def test_7_reconnect_device_code_connect_imx(self): self.assertEqual(TestConfig.WALLET_ADDRESS, output.get_text()) # Logout - print("Logging out...") - self.setupChrome() - bring_sample_app_to_foreground() - self.altdriver.find_object(By.NAME, "LogoutBtn").tap() - time.sleep(5) - bring_sample_app_to_foreground() - - # Wait for authenticated screen - self.altdriver.wait_for_current_scene_to_be("UnauthenticatedScene") - self.seleniumdriver.quit() - print("Logged out") \ No newline at end of file + self.logout() \ No newline at end of file diff --git a/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs b/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs index ecc8fa46..4d7e4f6a 100644 --- a/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs +++ b/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs @@ -113,7 +113,7 @@ public UniTask Login(bool useCachedSession = false) _pkceCompletionSource = task; _pkceLoginOnly = true; #if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) - WindowsDeepLink.Initialise(redirectUri, OnDeepLinkActivated); + WindowsDeepLink.Initialise(_redirectUri, OnDeepLinkActivated); #endif _ = LaunchAuthUrl(); return task.Task; @@ -189,7 +189,7 @@ public async UniTask ConnectImx(bool useCachedSession = false) _pkceLoginOnly = false; #if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) - WindowsDeepLink.Initialise(redirectUri, OnDeepLinkActivated); + WindowsDeepLink.Initialise(_redirectUri, OnDeepLinkActivated); #endif _ = LaunchAuthUrl(); @@ -434,7 +434,7 @@ public async UniTask Logout(bool hardLogout = true) var task = new UniTaskCompletionSource(); _pkceCompletionSource = task; #if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) - WindowsDeepLink.Initialise(logoutRedirectUri, OnDeepLinkActivated); + WindowsDeepLink.Initialise(_logoutRedirectUri, OnDeepLinkActivated); #endif LaunchLogoutPkceUrl(hardLogout); return await task.Task; diff --git a/src/Packages/Passport/Runtime/ThirdParty/Gree/Assets/Plugins/WebViewObject.cs b/src/Packages/Passport/Runtime/ThirdParty/Gree/Assets/Plugins/WebViewObject.cs index 2bf5d780..e2e01d08 100644 --- a/src/Packages/Passport/Runtime/ThirdParty/Gree/Assets/Plugins/WebViewObject.cs +++ b/src/Packages/Passport/Runtime/ThirdParty/Gree/Assets/Plugins/WebViewObject.cs @@ -311,7 +311,7 @@ public void EvaluateJS(string js) public void LaunchAuthURL(string url, string redirectUri) { -#if UNITY_STANDALONE_OSX || (UNITY_ANDROID && UNITY_EDITOR_OSX) || (UNITY_IPHONE && UNITY_EDITOR_OSX) +#if !IMMUTABLE_E2E_TESTING && (UNITY_STANDALONE_OSX || (UNITY_ANDROID && UNITY_EDITOR_OSX) || (UNITY_IPHONE && UNITY_EDITOR_OSX)) if (webView == IntPtr.Zero) return; _CImmutableWebViewPlugin_LaunchAuthURL(webView, url, redirectUri != null ? redirectUri : ""); From 220e8eed860ada888a68dbb3b5dcbd62f80927c4 Mon Sep 17 00:00:00 2001 From: Natalie Bunduwongse Date: Tue, 17 Jun 2025 10:53:03 +1200 Subject: [PATCH 4/8] fix: windows private fields --- .../Runtime/Scripts/Public/Passport.cs | 30 +++++++++---------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs b/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs index 5415e107..338bb680 100644 --- a/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs +++ b/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs @@ -37,7 +37,7 @@ public class Passport private PassportImpl? _passportImpl; public string Environment { get; private set; } - private IWebBrowserClient _webBrowserClient; + private IWebBrowserClient? _webBrowserClient; // Keeps track of the latest received deeplink private static string? _deeplink; @@ -140,7 +140,7 @@ private Passport() /// The URL where the browser will redirect after successful authentication. /// The URL where the browser will redirect after logout is complete. /// (Windows only) Timeout duration in milliseconds to wait for the default Windows browser engine to start. - /// (Windows only) Custom Windows browser to use instead of the default browser in the SDK. + /// (Windows only) Custom Windows browser to use instead of the default browser in the SDK. public static UniTask Init( string clientId, string environment, @@ -148,7 +148,7 @@ public static UniTask Init( string logoutRedirectUri #if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) , int engineStartupTimeoutMs = 60000, - IWindowsWebBrowserClient windowsWebBrowserClient = null + IWindowsWebBrowserClient? windowsWebBrowserClient = null #endif ) { @@ -202,10 +202,10 @@ string logoutRedirectUri /// Initialises the appropriate web browser and sets up browser communication. /// /// (Windows only) Timeout duration in milliseconds to wait for the default Windows browser engine to start. - /// (Windows only) Custom Windows browser to use instead of the default browser in the SDK. + /// (Windows only) Custom Windows browser to use instead of the default browser in the SDK. private async UniTask Initialise( #if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) - int engineStartupTimeoutMs, IWindowsWebBrowserClient windowsWebBrowserClient + int engineStartupTimeoutMs, IWindowsWebBrowserClient? windowsWebBrowserClient #endif ) { @@ -216,8 +216,8 @@ private async UniTask Initialise( if (windowsWebBrowserClient != null) { // Use the provided custom Windows browser client - this.webBrowserClient = new WindowsWebBrowserClientAdapter(windowsWebBrowserClient); - await ((WindowsWebBrowserClientAdapter)this.webBrowserClient).Init(); + _webBrowserClient = new WindowsWebBrowserClientAdapter(windowsWebBrowserClient); + await ((WindowsWebBrowserClientAdapter)_webBrowserClient).Init(); } else { @@ -225,9 +225,9 @@ private async UniTask Initialise( throw new PassportException("When 'IMMUTABLE_CUSTOM_BROWSER' is defined in Scripting Define Symbols, " + " 'windowsWebBrowserClient' must not be null."); #else - webBrowserClient = gameObject.AddComponent(); - await ((UwbWebView)webBrowserClient).Init(engineStartupTimeoutMs, _redactTokensInLogs, RedactTokenValues); - readySignalReceived = true; + _webBrowserClient = gameObject.AddComponent(); + await ((UwbWebView)_webBrowserClient).Init(engineStartupTimeoutMs, _redactTokensInLogs, RedactTokenValues); + _readySignalReceived = true; #endif } #elif (UNITY_ANDROID && !UNITY_EDITOR_WIN) || (UNITY_IPHONE && !UNITY_EDITOR_WIN) || UNITY_STANDALONE_OSX || UNITY_WEBGL @@ -543,7 +543,7 @@ public void ClearStorage() /// private static void SetDefaultWindowsBrowserLogLevel() { - if (Instance?.webBrowserClient is WebBrowserClient browserClient) + if (Instance?._webBrowserClient is WebBrowserClient browserClient) { browserClient.logSeverity = _logLevel switch { @@ -557,7 +557,7 @@ private static void SetDefaultWindowsBrowserLogLevel() private static void SetWindowsRedactionHandler() { - if (Instance?.webBrowserClient is WebBrowserClient browserClient) + if (Instance?._webBrowserClient is WebBrowserClient browserClient) { browserClient.Logger = new DefaultUnityWebBrowserLogger(redactionHandler: _redactTokensInLogs ? RedactTokenValues : null); } @@ -651,10 +651,10 @@ private void DisposeAll() { // Dispose of the web browser client for Windows only #if UNITY_STANDALONE_WIN || (UNITY_ANDROID && UNITY_EDITOR_WIN) || (UNITY_IPHONE && UNITY_EDITOR_WIN) - if (webBrowserClient != null) + if (_webBrowserClient != null) { - webBrowserClient.Dispose(); - webBrowserClient = null; + _webBrowserClient.Dispose(); + _webBrowserClient = null; } #endif From 7dc1068f4d2723d5ae2ab5c7420c6055ae68f83e Mon Sep 17 00:00:00 2001 From: Natalie Bunduwongse Date: Tue, 17 Jun 2025 11:53:08 +1200 Subject: [PATCH 5/8] test: clean up requirements file --- sample/Tests/requirements-desktop.txt | 4 +--- sample/Tests/requirements-mobile.txt | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/sample/Tests/requirements-desktop.txt b/sample/Tests/requirements-desktop.txt index d8c4eab0..7cdbe222 100644 --- a/sample/Tests/requirements-desktop.txt +++ b/sample/Tests/requirements-desktop.txt @@ -1,6 +1,4 @@ -AltTester_Driver==2.1.1 -google_api_python_client==2.136.0 -google_auth_oauthlib==1.2.0 +AltTester-Driver==2.1.1 protobuf==5.27.2 selenium==4.22.0 pytest==8.2.2 diff --git a/sample/Tests/requirements-mobile.txt b/sample/Tests/requirements-mobile.txt index a4eb2323..47c50dbc 100644 --- a/sample/Tests/requirements-mobile.txt +++ b/sample/Tests/requirements-mobile.txt @@ -1,6 +1,4 @@ -AltTester_Driver==2.1.1 -google_api_python_client==2.136.0 -google_auth_oauthlib==1.2.0 +AltTester-Driver==2.1.1 protobuf==5.27.2 selenium==4.22.0 pytest==8.2.2 From 6c195b47763c6f1aec853f3bb24bad862743f8d3 Mon Sep 17 00:00:00 2001 From: Natalie Bunduwongse Date: Tue, 17 Jun 2025 12:43:39 +1200 Subject: [PATCH 6/8] test: remove device code auth from windows test --- sample/Tests/test/test_windows.py | 28 +++++------------------ sample/Tests/test/test_windows_helpers.py | 11 ++------- 2 files changed, 8 insertions(+), 31 deletions(-) diff --git a/sample/Tests/test/test_windows.py b/sample/Tests/test/test_windows.py index 2b04fc53..cea2ab65 100644 --- a/sample/Tests/test/test_windows.py +++ b/sample/Tests/test/test_windows.py @@ -25,13 +25,7 @@ def restart_app_and_altdriver(self): time.sleep(5) # Give time for the app to open self.start_altdriver() - def select_auth_type(self, use_pkce: bool): - auth_type = "PKCE" if use_pkce else "DeviceCodeAuth" - self.get_altdriver().find_object(By.NAME, auth_type).tap() - - def login(self, use_pkce: bool): - self.select_auth_type(use_pkce) - + def login(self): # Wait for unauthenticated screen self.get_altdriver().wait_for_current_scene_to_be("UnauthenticatedScene") @@ -46,7 +40,7 @@ def login(self, use_pkce: bool): launch_browser() bring_sample_app_to_foreground() login_button.tap() - login(use_pkce) + login() bring_sample_app_to_foreground() # Wait for authenticated screen @@ -88,12 +82,8 @@ def login(self, use_pkce: bool): else: raise SystemExit(f"Failed to reset app {err}") - def test_1a_pkce_login(self): - self.login(True) - - def test_1b_device_code_login(self): - self.restart_app_and_altdriver() - self.login(False) + def test_1_login(self): + self.login() def test_2_other_functions(self): self.test_0_other_functions() @@ -110,9 +100,6 @@ def test_5_zkevm_functions(self): def test_6_relogin(self): self.restart_app_and_altdriver() - # Select use device code auth - self.select_auth_type(use_pkce=False) - # Relogin print("Re-logging in...") self.get_altdriver().wait_for_object(By.NAME, "ReloginBtn").tap() @@ -130,12 +117,9 @@ def test_6_relogin(self): self.get_altdriver().find_object(By.NAME, "ConnectBtn").tap() self.assertEqual("Connected to IMX", output.get_text()) - def test_7_reconnect_device_code_connect_imx(self): + def test_7_reconnect_connect_imx(self): self.restart_app_and_altdriver() - use_pkce = False - self.select_auth_type(use_pkce) - # Reconnect print("Reconnecting...") self.get_altdriver().wait_for_object(By.NAME, "ReconnectBtn").tap() @@ -171,7 +155,7 @@ def test_7_reconnect_device_code_connect_imx(self): launch_browser() bring_sample_app_to_foreground() self.get_altdriver().wait_for_object(By.NAME, "ConnectBtn").tap() - login(use_pkce) + login() bring_sample_app_to_foreground() # Wait for authenticated screen diff --git a/sample/Tests/test/test_windows_helpers.py b/sample/Tests/test/test_windows_helpers.py index 778ef5e0..be0238fa 100644 --- a/sample/Tests/test/test_windows_helpers.py +++ b/sample/Tests/test/test_windows_helpers.py @@ -39,7 +39,7 @@ def get_product_name(): # If regex fails, return default return "SampleApp" -def login(use_pkce: bool): +def login(): print("Connect to Chrome") # Set up Chrome options to connect to the existing Chrome instance chrome_options = Options() @@ -65,12 +65,6 @@ def login(use_pkce: bool): wait = WebDriverWait(driver, 60) - if not use_pkce: - print("Wait for device confirmation...") - contine_button = wait.until(EC.element_to_be_clickable((By.XPATH, "//button[span[text()='Continue']]"))) - contine_button.click() - print("Confirmed device") - print("Wait for email input...") email_field = wait.until(EC.presence_of_element_located((By.ID, ':r1:'))) print("Enter email...") @@ -96,8 +90,7 @@ def login(use_pkce: bool): otp_field.send_keys(code) print("Wait for success page...") - success_title = 'h1[data-testid="checking_title"]' if use_pkce else 'h1[data-testid="device_success_title"]' - wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, success_title))) + wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'h1[data-testid="checking_title"]'))) print("Connected to Passport!") driver.quit() From 803d8c10b0c62d8351f1183b2f2e4ada4d037053 Mon Sep 17 00:00:00 2001 From: Natalie Bunduwongse Date: Tue, 17 Jun 2025 17:00:38 +1200 Subject: [PATCH 7/8] fix: compilation errors --- .../Passport/Runtime/Scripts/Private/PassportImpl.cs | 6 +++--- src/Packages/Passport/Runtime/Scripts/Public/Passport.cs | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs b/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs index 4d7e4f6a..46acdec0 100644 --- a/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs +++ b/src/Packages/Passport/Runtime/Scripts/Private/PassportImpl.cs @@ -280,7 +280,7 @@ private async UniTask LaunchAuthUrl() string url = response.result.Replace(" ", "+"); #if UNITY_ANDROID && !UNITY_EDITOR loginPKCEUrl = url; - SendAuthEvent(pkceLoginOnly ? PassportAuthEvent.LoginPKCELaunchingCustomTabs : PassportAuthEvent.ConnectImxPKCELaunchingCustomTabs); + SendAuthEvent(_pkceLoginOnly ? PassportAuthEvent.LoginPKCELaunchingCustomTabs : PassportAuthEvent.ConnectImxPKCELaunchingCustomTabs); LaunchAndroidUrl(url); #else SendAuthEvent(_pkceLoginOnly ? PassportAuthEvent.LoginPKCEOpeningWebView : PassportAuthEvent.ConnectImxPKCEOpeningWebView); @@ -734,12 +734,12 @@ private void LaunchAndroidUrl(string url) #if (UNITY_IPHONE && !UNITY_EDITOR) || (UNITY_ANDROID && !UNITY_EDITOR) public void ClearCache(bool includeDiskFiles) { - communicationsManager.ClearCache(includeDiskFiles); + _communicationsManager.ClearCache(includeDiskFiles); } public void ClearStorage() { - communicationsManager.ClearStorage(); + _communicationsManager.ClearStorage(); } #endif diff --git a/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs b/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs index 338bb680..01f78cb2 100644 --- a/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs +++ b/src/Packages/Passport/Runtime/Scripts/Public/Passport.cs @@ -241,7 +241,7 @@ private async UniTask Initialise( BrowserCommunicationsManager communicationsManager = new BrowserCommunicationsManager(_webBrowserClient); #if UNITY_WEBGL - readySignalReceived = true; + _readySignalReceived = true; #else // Mark ready when browser is initialised and game bridge file is loaded communicationsManager.OnReady += () => _readySignalReceived = true; From 8cb65d08325fa09a852296ab42e05b5478d6755a Mon Sep 17 00:00:00 2001 From: Natalie Bunduwongse Date: Wed, 18 Jun 2025 14:36:50 +1200 Subject: [PATCH 8/8] test: fix windows login tab --- sample/Tests/test/test.py | 1 + sample/Tests/test/test_android.py | 1 + sample/Tests/test/test_mac.py | 1 + sample/Tests/test/test_windows.py | 1 + sample/Tests/test/test_windows_helpers.py | 35 +++++++++++++++++------ 5 files changed, 31 insertions(+), 8 deletions(-) diff --git a/sample/Tests/test/test.py b/sample/Tests/test/test.py index 6f46ed98..a073cbdb 100644 --- a/sample/Tests/test/test.py +++ b/sample/Tests/test/test.py @@ -93,6 +93,7 @@ def test_2_imx_functions(self): # Connect to IMX self.altdriver.find_object(By.NAME, "ConnectBtn").tap() + time.sleep(5) text = output.get_text() print(f"ConnectBtn output: {text}") self.assertEqual("Connected to IMX", text) diff --git a/sample/Tests/test/test_android.py b/sample/Tests/test/test_android.py index 287c0ec6..14e2d5f1 100644 --- a/sample/Tests/test/test_android.py +++ b/sample/Tests/test/test_android.py @@ -142,6 +142,7 @@ def test_6_pkce_relogin(self): # Click Connect to IMX button self.altdriver.find_object(By.NAME, "ConnectBtn").tap() + time.sleep(5) self.assertEqual("Connected to IMX", output.get_text()) self.altdriver.stop() diff --git a/sample/Tests/test/test_mac.py b/sample/Tests/test/test_mac.py index 58d83f4e..70dbc6e2 100644 --- a/sample/Tests/test/test_mac.py +++ b/sample/Tests/test/test_mac.py @@ -221,6 +221,7 @@ def test_6_relogin(self): # Click Connect to IMX button self.altdriver.find_object(By.NAME, "ConnectBtn").tap() + time.sleep(5) self.assertEqual("Connected to IMX", output.get_text()) self.altdriver.stop() diff --git a/sample/Tests/test/test_windows.py b/sample/Tests/test/test_windows.py index cea2ab65..583aa5b5 100644 --- a/sample/Tests/test/test_windows.py +++ b/sample/Tests/test/test_windows.py @@ -115,6 +115,7 @@ def test_6_relogin(self): # Click Connect to IMX button self.get_altdriver().find_object(By.NAME, "ConnectBtn").tap() + time.sleep(5) self.assertEqual("Connected to IMX", output.get_text()) def test_7_reconnect_connect_imx(self): diff --git a/sample/Tests/test/test_windows_helpers.py b/sample/Tests/test/test_windows_helpers.py index be0238fa..48ef6f61 100644 --- a/sample/Tests/test/test_windows_helpers.py +++ b/sample/Tests/test/test_windows_helpers.py @@ -56,12 +56,30 @@ def login(): # Get all window handles all_windows = driver.window_handles - - print("Find the new window") - new_window = [window for window in all_windows if window != driver.current_window_handle][0] - - print("Switch to the new window") - driver.switch_to.window(new_window) + + print(f"Found {len(all_windows)} new windows to check: {all_windows}") + + # Find the window with email input + target_window = None + for window in all_windows: + try: + print(f"Checking window: {window}") + driver.switch_to.window(window) + driver.find_element(By.ID, ':r1:') + target_window = window + print(f"Found email input in window: {window}") + break + except: + print(f"Email input not found in window: {window}, trying next...") + continue + + if not target_window: + print("Could not find email input field in any window!") + driver.quit() + return + + print("Switch to the target window") + driver.switch_to.window(target_window) wait = WebDriverWait(driver, 60) @@ -126,8 +144,9 @@ def bring_sample_app_to_foreground(): command = [ "powershell.exe", - "-Command", - f"Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process; & '{powershell_script_path}' -appName '{product_name}'" + "-ExecutionPolicy", "Bypass", + "-File", powershell_script_path, + "-appName", product_name ] subprocess.run(command, check=True)