Skip to content

Commit e46919d

Browse files
v1.4.0 (#10)
## Enhancements * Plugin Icon * Editor Toolbar Button for Settings Quick Access * ThirdwebEditor Module for editor-only functionality * External OAuth Browser * Per-provider OAuth settings config * Ecosystem Wallets Added * Phone Option to OTP auth methods * JWT, Auth Endpoint, and Guest Sign In methods * Discord, Farcaster, Telegram, Line, X, and Coinbase OAuth methods * InApp / Ecosystem Wallets to child structs * Examples updated to match changed structs / functions * External OAuth Complete screen * Static accessors to all Runtime settings ## Fixes * Google Auth on mobile via external OAuth ## Removals * Private Key functionality (Superseded by guest login) * Secret Key runtime setting - Safer to enforce client + bundle
1 parent 5885bb1 commit e46919d

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+2428
-773
lines changed
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
-502 Bytes
Binary file not shown.

Content/ThirdwebMacroLibrary.uasset

7.56 KB
Binary file not shown.

Resources/EditorToolbarButtonIcon.svg

Lines changed: 40 additions & 0 deletions
Loading

Resources/Icon128.png

7.03 KB
Loading
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:1e311209aa3b935090618546f4430113a75864b9455e23b9b9476765c84031a9
3-
size 87144306
2+
oid sha256:e01bbd3d866be1ee38b9d2a685a5121433166ff3e6217cd3a9501daf5cb1c741
3+
size 88139448

Source/ThirdParty/IOS/libthirdweb.a

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:aca4fd5d371de5f1ff3ebd022a6beeb16fb707c875c565fbf63e5abec2c7d280
3-
size 60426152
2+
oid sha256:147b9d574fa190f37049726141b07b51190fc9d31db7ea9b52d65b0b7b4a6d5e
3+
size 61070584
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:f10835df3845840eb8041ac7def2a215fd0057f82c4104e5497062c3614aa9af
3-
size 60292464
2+
oid sha256:920ef0f96003a52d98c7df57c1cccc63ca7b634051fcbf157de6c352faf73d06
3+
size 60929776

Source/ThirdParty/Linux/libthirdweb.a

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:8c2c127fd260c182a027a33f8e15c2ca71f158338ea56bccf9f150b95174dc2e
3-
size 92429216
2+
oid sha256:9fda3a500ad6a00d54943bfaf4cf393cba1a045babc8e1c342e60e2e54c686fb
3+
size 93468634
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:9618e0028b7b79a8b60098a338d656f6b8d7b1cddaafff615d3879d101d90c35
3-
size 93394062
2+
oid sha256:180f39bb699712903d2bb1c45956a675e4d0b82ab957273a9ec7a7b4d03b6896
3+
size 94435570

Source/ThirdParty/Mac/libthirdweb.a

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:d8a4cbcd505ab63d93e027978e17f5807152ee526c53e3632bd7bae188fdfcb3
3-
size 121257384
2+
oid sha256:b93633b9a8401b92da3d2d9f3022fdbf4b774f95b3f720d1a57d33d45ab0d6bf
3+
size 122544136
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
version https://git-lfs.github.com/spec/v1
2-
oid sha256:503601925637c00032b1ffd2b943baa624de58643a8155153eeb5224123958b6
3-
size 91595106
2+
oid sha256:499e450d8a5c79255d7f2f41b059a82f003c47735affb2f76e9f470900b69348
3+
size 93015574

Source/Thirdweb/Private/AsyncTasks/AsyncTaskThirdwebLoginWithOAuth.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ void UAsyncTaskThirdwebLoginWithOAuth::Activate()
2323
Browser->Authenticate(Wallet);
2424
}
2525

26-
UAsyncTaskThirdwebLoginWithOAuth* UAsyncTaskThirdwebLoginWithOAuth::LoginWithOAuth(UObject* WorldContextObject, const FWalletHandle& Wallet)
26+
UAsyncTaskThirdwebLoginWithOAuth* UAsyncTaskThirdwebLoginWithOAuth::LoginWithOAuth(UObject* WorldContextObject, const FInAppWalletHandle& Wallet)
2727
{
2828
if (!WorldContextObject)
2929
{

Source/Thirdweb/Private/Browser/ThirdwebOAuthBrowserUserWidget.cpp

Lines changed: 61 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,12 @@
33
#include "Browser/ThirdwebOAuthBrowserUserWidget.h"
44

55
#include "ThirdwebLog.h"
6+
#include "ThirdwebRuntimeSettings.h"
67

78
#include "Blueprint/WidgetTree.h"
89

910
#include "Browser/ThirdwebOAuthBrowserWidget.h"
11+
#include "Browser/ThirdwebOAuthExternalBrowser.h"
1012

1113
#include "Components/Button.h"
1214
#include "Components/Overlay.h"
@@ -36,12 +38,18 @@ TSharedRef<SWidget> UThirdwebOAuthBrowserUserWidget::RebuildWidget()
3638
Browser = WidgetTree->ConstructWidget<UThirdwebOAuthBrowserWidget>(UThirdwebOAuthBrowserWidget::StaticClass(), TEXT("ThirdwebOauthBrowser"));
3739
Browser->OnUrlChanged.AddUObject(this, &ThisClass::HandleUrlChanged);
3840
Browser->OnPageLoaded.AddUObject(this, &ThisClass::HandlePageLoaded);
41+
Browser->OnBeforePopup.AddUObject(this, &ThisClass::HandleOnBeforePopup);
3942
UPanelSlot* PanelSlot = RootWidget->AddChild(Browser);
4043
if (UOverlaySlot* RootWidgetSlot = Cast<UOverlaySlot>(PanelSlot))
4144
{
4245
RootWidgetSlot->SetHorizontalAlignment(HAlign_Fill);
4346
RootWidgetSlot->SetVerticalAlignment(VAlign_Fill);
4447
}
48+
49+
// Construct External browser
50+
ExternalBrowser = NewObject<UThirdwebOAuthExternalBrowser>(this);
51+
ExternalBrowser->OnAuthenticated.BindUObject(this, &ThisClass::HandleAuthenticated);
52+
ExternalBrowser->OnError.BindUObject(this, &ThisClass::HandleError);
4553
}
4654

4755
return Super::RebuildWidget();
@@ -60,25 +68,30 @@ void UThirdwebOAuthBrowserUserWidget::OnWidgetRebuilt()
6068
SetVisible(false);
6169
}
6270

63-
void UThirdwebOAuthBrowserUserWidget::Authenticate(const FWalletHandle& InAppWallet)
71+
void UThirdwebOAuthBrowserUserWidget::Authenticate(const FInAppWalletHandle& InAppWallet)
6472
{
73+
// Validate Wallet
6574
if (!InAppWallet.IsValid())
6675
{
6776
TW_LOG(Error, TEXT("OAuthBrowserUserWidget::Authenticate::Wallet invalid"));
68-
return OnError.Broadcast(TEXT("Invalid Wallet"));
77+
return HandleError(TEXT("Invalid Wallet"));
6978
}
7079
Wallet = InAppWallet;
80+
81+
// Get Login URL
82+
FString Link;
83+
if (FString Error; !Wallet.FetchOAuthLoginURL(Browser->DummyUrl, Link, Error))
84+
{
85+
return HandleError(Error);
86+
}
87+
TW_LOG(Verbose, TEXT("OAuthBrowserUserWidget::Authenticate::Authenticating against %s"), *Link);
7188

72-
if (Browser)
89+
// Check Browser Type
90+
if (UThirdwebRuntimeSettings::IsExternalOAuthBackend(Wallet.GetOAuthProvider()))
7391
{
74-
FString Error;
75-
if (FString Link; Wallet.FetchOAuthLoginURL(Browser->DummyUrl, Link, Error))
76-
{
77-
TW_LOG(Verbose, TEXT("OAuthBrowserUserWidget::Authenticate::Authenticating against %s"), *Link);
78-
return Browser->Authenticate(Link);
79-
}
80-
OnError.Broadcast(Error);
92+
return ExternalBrowser->Authenticate(Link);
8193
}
94+
return Browser->Authenticate(Link);
8295
}
8396

8497

@@ -89,10 +102,19 @@ bool UThirdwebOAuthBrowserUserWidget::IsBlank() const
89102
return Url.IsEmpty() || Url.StartsWith(BackendUrlPrefix);
90103
}
91104

105+
FString UThirdwebOAuthBrowserUserWidget::GetUrl() const
106+
{
107+
if (Browser)
108+
{
109+
return Browser->GetUrl();
110+
}
111+
return TEXT("");
112+
}
113+
92114
void UThirdwebOAuthBrowserUserWidget::HandleUrlChanged(const FString& Url)
93115
{
94116
TW_LOG(Verbose, TEXT("OAuthBrowserUserWidget::HandleUrlChanged::%s"), *Url);
95-
if (Url.IsEmpty() || Url.StartsWith(BackendUrlPrefix))
117+
if (Url.IsEmpty() || (Url.StartsWith(BackendUrlPrefix) && !Url.StartsWith(BackendUrlPrefix + TEXT("sdk/oauth"))))
96118
{
97119
return SetVisible(false);
98120
}
@@ -102,9 +124,9 @@ void UThirdwebOAuthBrowserUserWidget::HandleUrlChanged(const FString& Url)
102124
FString Left, Right;
103125
if (Url.Split(TEXT("authResult="), &Left, &Right, ESearchCase::IgnoreCase))
104126
{
105-
return OnAuthenticated.Broadcast(Right);
127+
return HandleAuthenticated(Right);
106128
}
107-
return OnError.Broadcast(TEXT("Failed to match AuthResult in url"));
129+
return HandleError(TEXT("Failed to match AuthResult in url"));
108130
}
109131
bShouldBeVisible = true;
110132
}
@@ -117,6 +139,32 @@ void UThirdwebOAuthBrowserUserWidget::HandlePageLoaded(const FString& Url)
117139
}
118140
}
119141

142+
void UThirdwebOAuthBrowserUserWidget::HandleOnBeforePopup(const FString& Url, const FString& Frame)
143+
{
144+
145+
if (UPanelWidget* RootWidget = Cast<UPanelWidget>(GetRootWidget()))
146+
{
147+
// Construct browser widget
148+
UThirdwebOAuthBrowserWidget* Popup = WidgetTree->ConstructWidget<UThirdwebOAuthBrowserWidget>(UThirdwebOAuthBrowserWidget::StaticClass(), TEXT("ThirdwebOAuthBrowserPopUp"));
149+
Popup->OnUrlChanged.AddUObject(this, &ThisClass::HandleUrlChanged);
150+
Popup->OnPageLoaded.AddUObject(this, &ThisClass::HandlePageLoaded);
151+
Popup->OnBeforePopup.AddUObject(this, &ThisClass::HandleOnBeforePopup);
152+
RootWidget->AddChild(Popup);
153+
Popup->LoadUrl(Url);
154+
}
155+
return OnPopup.Broadcast(Url, Frame);
156+
}
157+
158+
void UThirdwebOAuthBrowserUserWidget::HandleAuthenticated(const FString& AuthResult)
159+
{
160+
OnAuthenticated.Broadcast(AuthResult);
161+
}
162+
163+
void UThirdwebOAuthBrowserUserWidget::HandleError(const FString& Error)
164+
{
165+
OnError.Broadcast(Error);
166+
}
167+
120168
void UThirdwebOAuthBrowserUserWidget::SetVisible(const bool bVisible)
121169
{
122170
// Mobile webview needs to be visible to work

Source/Thirdweb/Private/Browser/ThirdwebOAuthBrowserWidget.cpp

Lines changed: 100 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
return; \
2222
}
2323

24-
const FString UThirdwebOAuthBrowserWidget::DummyUrl = TEXT("about:blank");
24+
const FString UThirdwebOAuthBrowserWidget::DummyUrl = TEXT("http://localhost:8789/callback");
2525

2626
bool UThirdwebOAuthBrowserWidget::IsPageLoaded() const
2727
{
@@ -66,7 +66,7 @@ void UThirdwebOAuthBrowserWidget::Authenticate(const FString& OAuthLoginUrl)
6666
{
6767
#if WITH_CEF
6868
ENSURE_VALID_BROWSER("Authenticate")
69-
TW_LOG(Verbose, TEXT("OAuthBrowserWidget::Authenticate::Loading %s"), *OAuthLoginUrl);
69+
TW_LOG(Log, TEXT("OAuthBrowserWidget::Authenticate::Loading %s"), *OAuthLoginUrl);
7070
Browser->LoadURL(OAuthLoginUrl);
7171
#endif
7272
}
@@ -75,24 +75,105 @@ void UThirdwebOAuthBrowserWidget::HandleUrlChanged(const FText& InUrl)
7575
{
7676
#if WITH_CEF
7777
ENSURE_VALID_BROWSER("HandleUrlChanged")
78-
FString Url = InUrl.ToString();
79-
TW_LOG(Verbose, TEXT("UThirdwebOAuthBrowserWidget::HandleUrlChanged:%s"), *Url);
80-
if (Url.IsEmpty())
78+
if (IsInGameThread())
8179
{
82-
Url = Browser->GetUrl();
80+
FString Url = InUrl.ToString();
81+
if (Url.IsEmpty())
82+
{
83+
Url = Browser->GetUrl();
84+
}
85+
TW_LOG(Log, TEXT("ThirdwebOAuthBrowserWidget::HandleUrlChanged:%s"), *Url);
86+
OnUrlChanged.Broadcast(FGenericPlatformHttp::UrlDecode(Url));
8387
}
84-
TW_LOG(Verbose, TEXT("UThirdwebOAuthBrowserWidget::HandleUrlChanged:%s"), *Url);
85-
// Ensure this code runs on the game thread
86-
AsyncTask(ENamedThreads::GameThread, [&, Url]() { if (IsInGameThread()) OnUrlChanged.Broadcast(FGenericPlatformHttp::UrlDecode(Url)); });
88+
else
89+
{
90+
// Retry on the GameThread.
91+
TWeakObjectPtr<UThirdwebOAuthBrowserWidget> WeakThis = this;
92+
FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, InUrl]()
93+
{
94+
if (WeakThis.IsValid())
95+
{
96+
WeakThis->HandleUrlChanged(InUrl);
97+
}
98+
}, TStatId(), nullptr, ENamedThreads::GameThread);
99+
}
100+
87101
#endif
88102
}
89103

90104
void UThirdwebOAuthBrowserWidget::HandleOnLoadComplete()
91105
{
92106
#if WITH_CEF
93107
ENSURE_VALID_BROWSER("HandleOnLoadComplete")
94-
FString Url = Browser->GetUrl();
95-
AsyncTask(ENamedThreads::GameThread, [&, Url]() { if (IsInGameThread()) OnPageLoaded.Broadcast(FGenericPlatformHttp::UrlDecode(Url)); });
108+
if (IsInGameThread())
109+
{
110+
TW_LOG(Log, TEXT("ThirdwebOAuthBrowserWidget::HandleOnLoadComplete:%s"), *Browser->GetUrl());
111+
OnPageLoaded.Broadcast(FGenericPlatformHttp::UrlDecode(Browser->GetUrl()));
112+
}
113+
else
114+
{
115+
// Retry on the GameThread.
116+
TWeakObjectPtr<UThirdwebOAuthBrowserWidget> WeakThis = this;
117+
FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis]()
118+
{
119+
if (WeakThis.IsValid())
120+
{
121+
WeakThis->HandleOnLoadComplete();
122+
}
123+
}, TStatId(), nullptr, ENamedThreads::GameThread);
124+
}
125+
#endif
126+
}
127+
128+
bool UThirdwebOAuthBrowserWidget::HandleOnBeforePopup(FString URL, FString Frame)
129+
{
130+
TW_LOG(Log, TEXT("ThirdwebOAuthBrowserWidget::HandleOnBeforePopup::%s | %s"), *URL, *Frame)
131+
if (OnBeforePopup.IsBound())
132+
{
133+
if (IsInGameThread())
134+
{
135+
OnBeforePopup.Broadcast(URL, Frame);
136+
}
137+
else
138+
{
139+
// Retry on the GameThread.
140+
TWeakObjectPtr<UThirdwebOAuthBrowserWidget> WeakThis = this;
141+
FFunctionGraphTask::CreateAndDispatchWhenReady([WeakThis, URL, Frame]()
142+
{
143+
if (WeakThis.IsValid())
144+
{
145+
WeakThis->HandleOnBeforePopup(URL, Frame);
146+
}
147+
}, TStatId(), nullptr, ENamedThreads::GameThread);
148+
}
149+
return true;
150+
}
151+
return false;
152+
}
153+
154+
bool UThirdwebOAuthBrowserWidget::HandleOnCreateWindow(const TWeakPtr<IWebBrowserWindow>& Window, const TWeakPtr<IWebBrowserPopupFeatures>& Features)
155+
{
156+
TW_LOG(Error, TEXT("ThirdwebOAuthBrowserWidget::HandleOnLoadError"))
157+
return false;
158+
}
159+
160+
void UThirdwebOAuthBrowserWidget::HandleOnLoadError()
161+
{
162+
TW_LOG(Error, TEXT("ThirdwebOAuthBrowserWidget::HandleOnLoadError"))
163+
}
164+
165+
bool UThirdwebOAuthBrowserWidget::HandleOnCloseWindow(const TWeakPtr<IWebBrowserWindow>& Window)
166+
{
167+
TW_LOG(Log, TEXT("ThirdwebOAuthBrowserWidget::HandleOnCloseWindow"))
168+
RemoveFromParent();
169+
return true;
170+
}
171+
172+
void UThirdwebOAuthBrowserWidget::LoadUrl(const FString& Url)
173+
{
174+
#if WITH_CEF
175+
ENSURE_VALID_BROWSER("LoadUrl")
176+
Browser->LoadURL(Url);
96177
#endif
97178
}
98179

@@ -104,15 +185,21 @@ TSharedRef<SWidget> UThirdwebOAuthBrowserWidget::RebuildWidget()
104185
Browser = SNew(SWebBrowser)
105186
.InitialURL(InitialUrl)
106187
.ShowControls(false)
188+
.ShowAddressBar(false)
189+
// .PopupMenuMethod(EPopupMethod::UseCurrentWindow)
107190
.SupportsTransparency(bSupportsTransparency)
108191
.ShowInitialThrobber(bShowInitialThrobber)
192+
.OnCreateWindow(BIND_UOBJECT_DELEGATE(FOnCreateWindowDelegate ,HandleOnCreateWindow))
193+
.OnLoadError(BIND_UOBJECT_DELEGATE(FSimpleDelegate, HandleOnLoadError))
194+
.OnUrlChanged(BIND_UOBJECT_DELEGATE(FOnTextChanged, HandleUrlChanged))
109195
.OnLoadCompleted(BIND_UOBJECT_DELEGATE(FSimpleDelegate, HandleOnLoadComplete))
110-
.OnUrlChanged(BIND_UOBJECT_DELEGATE(FOnTextChanged, HandleUrlChanged));
196+
.OnCloseWindow(BIND_UOBJECT_DELEGATE(FOnCloseWindowDelegate, HandleOnCloseWindow))
197+
.OnBeforePopup(BIND_UOBJECT_DELEGATE(FOnBeforePopupDelegate, HandleOnBeforePopup));
111198

112199
return Browser.ToSharedRef();
113200
}
114201
#endif
115-
return SNew(SBox).HAlign(HAlign_Center).VAlign(VAlign_Center)
202+
return SNew(SBox).HAlign(HAlign_Fill).VAlign(VAlign_Fill)
116203
[
117204
SNew(STextBlock).Text(NSLOCTEXT("Thirdweb", "Thirdweb OAuth Browser", "Thirdweb OAuth Browser"))
118205
];

0 commit comments

Comments
 (0)