diff --git a/Source/Immutable/Private/Immutable/Actions/ImtblPassportLogoutAsyncAction.cpp b/Source/Immutable/Private/Immutable/Actions/ImtblPassportLogoutAsyncAction.cpp index a606a379..89374693 100644 --- a/Source/Immutable/Private/Immutable/Actions/ImtblPassportLogoutAsyncAction.cpp +++ b/Source/Immutable/Private/Immutable/Actions/ImtblPassportLogoutAsyncAction.cpp @@ -6,11 +6,12 @@ #include "Immutable/ImmutableSubsystem.h" #include "Immutable/Misc/ImtblLogging.h" -UImtblPassportLogoutAsyncAction* UImtblPassportLogoutAsyncAction::Logout(UObject* WorldContextObject) +UImtblPassportLogoutAsyncAction* UImtblPassportLogoutAsyncAction::Logout(UObject* WorldContextObject, bool DoHardLogout) { UImtblPassportLogoutAsyncAction* PassportInitBlueprintNode = NewObject(); PassportInitBlueprintNode->WorldContextObject = WorldContextObject; + PassportInitBlueprintNode->bDoHardLogout = DoHardLogout; return PassportInitBlueprintNode; } @@ -19,21 +20,22 @@ void UImtblPassportLogoutAsyncAction::Activate() { if (!WorldContextObject || !WorldContextObject->GetWorld()) { - FString Err = "Logout failed due to missing world or world context object."; - IMTBL_WARN("%s", *Err) - OnFailure.Broadcast(Err); + const FString ErrorMessage = "Logout failed due to missing world or world context object."; + + IMTBL_WARN("%s", *ErrorMessage) + OnFailure.Broadcast(ErrorMessage); + return; } - GetSubsystem()->WhenReady(this, &UImtblPassportLogoutAsyncAction::DoLogout); //, /* timoutSec */ 15.0f); + GetSubsystem()->WhenReady(this, &UImtblPassportLogoutAsyncAction::DoLogout); } void UImtblPassportLogoutAsyncAction::DoLogout(TWeakObjectPtr JSConnector) { - // Get Passport auto Passport = GetSubsystem()->GetPassport(); - // Run Logout - Passport->Logout(UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImtblPassportLogoutAsyncAction::OnLogoutResponse)); + + Passport->Logout(bDoHardLogout, UImmutablePassport::FImtblPassportResponseDelegate::CreateUObject(this, &UImtblPassportLogoutAsyncAction::OnLogoutResponse)); } void UImtblPassportLogoutAsyncAction::OnLogoutResponse(FImmutablePassportResult Result) const diff --git a/Source/Immutable/Private/Immutable/ImmutablePassport.cpp b/Source/Immutable/Private/Immutable/ImmutablePassport.cpp index 4f81d117..7cea7066 100644 --- a/Source/Immutable/Private/Immutable/ImmutablePassport.cpp +++ b/Source/Immutable/Private/Immutable/ImmutablePassport.cpp @@ -174,7 +174,7 @@ void UImmutablePassport::ConnectPKCE(bool IsConnectImx, const FImtblPassportResp } #endif -void UImmutablePassport::Logout(const FImtblPassportResponseDelegate& ResponseDelegate) +void UImmutablePassport::Logout(bool DoHardLogout, const FImtblPassportResponseDelegate& ResponseDelegate) { #if PLATFORM_ANDROID | PLATFORM_IOS | PLATFORM_MAC if (IsStateFlagsSet(IPS_PKCE) || bIsPrevConnectedViaPKCEFlow) @@ -184,6 +184,10 @@ void UImmutablePassport::Logout(const FImtblPassportResponseDelegate& ResponseDe #endif if (IsStateFlagsSet(IPS_CONNECTED)) { + if (DoHardLogout) + { + SetStateFlags(IPS_HARDLOGOUT); + } CallJS(ImmutablePassportAction::Logout, TEXT(""), ResponseDelegate, FImtblJSResponseDelegate::CreateUObject(this, &UImmutablePassport::OnLogoutResponse)); } else @@ -428,60 +432,79 @@ void UImmutablePassport::OnInitDeviceFlowResponse(FImtblJSResponse Response) void UImmutablePassport::OnLogoutResponse(FImtblJSResponse Response) { - if (auto ResponseDelegate = GetResponseDelegate(Response)) + auto ResponseDelegate = GetResponseDelegate(Response); + + if (!ResponseDelegate) { - if (Response.success) - { - FString Url; - FString Err; + return; + } - Response.JsonObject->TryGetStringField(TEXT("result"), Url); - if (!Url.IsEmpty()) - { + FString Message; + + if (!Response.success) + { + Message = Response.Error.IsSet() ? Response.Error->ToString() : Response.JsonObject->GetStringField(TEXT("error")); + + IMTBL_ERR("%s", *Message) + ResponseDelegate->ExecuteIfBound(FImmutablePassportResult{ Response.success, Message, Response }); + + return; + } + + if (!IsStateFlagsSet(IPS_HARDLOGOUT)) + { + Message = "Logged out without clearing browser session"; + + IMTBL_LOG("%s", *Message) + ResponseDelegate->ExecuteIfBound(FImmutablePassportResult{ true, Message }); + + return; + } + + FString Url; + FString ErrorMessage; + + ResetStateFlags(IPS_HARDLOGOUT); + Response.JsonObject->TryGetStringField(TEXT("result"), Url); + if (!Url.IsEmpty()) + { #if PLATFORM_ANDROID | PLATFORM_IOS | PLATFORM_MAC - if (IsStateFlagsSet(IPS_PKCE) || bIsPrevConnectedViaPKCEFlow) - { - OnHandleDeepLink = FImtblPassportHandleDeepLinkDelegate::CreateUObject(this, &UImmutablePassport::OnDeepLinkActivated); + if (IsStateFlagsSet(IPS_PKCE) || bIsPrevConnectedViaPKCEFlow) + { + OnHandleDeepLink = FImtblPassportHandleDeepLinkDelegate::CreateUObject(this, &UImmutablePassport::OnDeepLinkActivated); #if PLATFORM_ANDROID - LaunchAndroidUrl(Url); + LaunchAndroidUrl(Url); #elif PLATFORM_IOS - [[ImmutableIOS instance] launchUrl:TCHAR_TO_ANSI(*Url)]; + [[ImmutableIOS instance] launchUrl:TCHAR_TO_ANSI(*Url)]; #elif PLATFORM_MAC - [[ImmutableMac instance] launchUrl:TCHAR_TO_ANSI(*Url) forRedirectUri:TCHAR_TO_ANSI(*InitData.logoutRedirectUri)]; -#endif - } - else - { -#endif - FPlatformProcess::LaunchURL(*Url, nullptr, &Err); - if (Err.Len()) - { - FString Msg = "Failed to connect to Browser: " + Err; - IMTBL_ERR("%s", *Msg); - ResponseDelegate->ExecuteIfBound(FImmutablePassportResult{false, Msg, Response}); - return; - } - IMTBL_LOG("Logged out.") - ResponseDelegate->ExecuteIfBound(FImmutablePassportResult{Response.success, "Logged out"}); -#if PLATFORM_ANDROID | PLATFORM_IOS | PLATFORM_MAC - } + [[ImmutableMac instance] launchUrl:TCHAR_TO_ANSI(*Url) forRedirectUri:TCHAR_TO_ANSI(*InitData.logoutRedirectUri)]; #endif - } - else - { - ResponseDelegate->ExecuteIfBound(FImmutablePassportResult{false, "Logout Url is empty", Response}); - } - ResetStateFlags(IPS_CONNECTED); } else { - FString Msg = Response.Error.IsSet() ? Response.Error->ToString() : Response.JsonObject->GetStringField(TEXT("error")); - - ResponseDelegate->ExecuteIfBound(FImmutablePassportResult{Response.success, Msg, Response}); +#endif + FPlatformProcess::LaunchURL(*Url, nullptr, &ErrorMessage); + if (ErrorMessage.Len()) + { + Message = "Failed to connect to Browser: " + ErrorMessage; + + IMTBL_ERR("%s", *Message); + ResponseDelegate->ExecuteIfBound(FImmutablePassportResult{ false, Message, Response }); - IMTBL_ERR("Error logging out.") + return; + } + Message = "Logged out"; + IMTBL_LOG("%s", *Message) + ResponseDelegate->ExecuteIfBound(FImmutablePassportResult{ Response.success, Message }); +#if PLATFORM_ANDROID | PLATFORM_IOS | PLATFORM_MAC } +#endif + } + else + { + ResponseDelegate->ExecuteIfBound(FImmutablePassportResult{false, "Logout Url is empty", Response}); } + ResetStateFlags(IPS_CONNECTED); } void UImmutablePassport::OnConnectSilentResponse(FImtblJSResponse Response) diff --git a/Source/Immutable/Public/Immutable/Actions/ImtblPassportLogoutAsyncAction.h b/Source/Immutable/Public/Immutable/Actions/ImtblPassportLogoutAsyncAction.h index cf2525a7..82220197 100644 --- a/Source/Immutable/Public/Immutable/Actions/ImtblPassportLogoutAsyncAction.h +++ b/Source/Immutable/Public/Immutable/Actions/ImtblPassportLogoutAsyncAction.h @@ -18,7 +18,7 @@ class IMMUTABLE_API UImtblPassportLogoutAsyncAction : public UImtblBlueprintAsyn public: UFUNCTION(BlueprintCallable, meta = (WorldContext = "WorldContextObject", BlueprintInternalUseOnly = "true"), Category = "Immutable") - static UImtblPassportLogoutAsyncAction* Logout(UObject* WorldContextObject); + static UImtblPassportLogoutAsyncAction* Logout(UObject* WorldContextObject, bool DoHardLogout = true); virtual void Activate() override; @@ -27,6 +27,8 @@ class IMMUTABLE_API UImtblPassportLogoutAsyncAction : public UImtblBlueprintAsyn void OnLogoutResponse(FImmutablePassportResult Result) const; private: + bool bDoHardLogout = true; + UPROPERTY(BlueprintAssignable) FPassportLogoutOutPin OnSuccess; UPROPERTY(BlueprintAssignable) diff --git a/Source/Immutable/Public/Immutable/ImmutablePassport.h b/Source/Immutable/Public/Immutable/ImmutablePassport.h index 717809d2..57605ff2 100644 --- a/Source/Immutable/Public/Immutable/ImmutablePassport.h +++ b/Source/Immutable/Public/Immutable/ImmutablePassport.h @@ -69,7 +69,7 @@ class IMMUTABLE_API UImmutablePassport : public UObject void ConnectPKCE(bool IsConnectImx, const FImtblPassportResponseDelegate& ResponseDelegate); #endif - void Logout(const FImtblPassportResponseDelegate& ResponseDelegate); + void Logout(bool DoHardLogout, const FImtblPassportResponseDelegate& ResponseDelegate); /** * Initializes the zkEVM provider. @@ -239,7 +239,8 @@ class IMMUTABLE_API UImmutablePassport : public UObject IPS_IMX = 1 << 2, IPS_PKCE = 1 << 3, IPS_COMPLETING_PKCE = 1 << 4, - IPS_INITIALIZED = 1 << 5 + IPS_INITIALIZED = 1 << 5, + IPS_HARDLOGOUT = 1 << 6 }; uint8 StateFlags = IPS_NONE;