Skip to content

Links IAP Leo purchase to desktop #22012

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public class BraveLeoPreferences extends BravePreferenceFragment
private static final String PREF_SUBSCRIPTION_CATEGORY = "subscription_category";
private static final String PREF_DEFAULT_MODEL = "default_model";
private static final String LINK_SUBSCRIPTION_URL =
"https://account.brave.com?intent=connect-receipt&product=leo";
"https://account.brave.com?intent=link-order&product=leo";

@Override
public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ AIChatIAPSubscription::AIChatIAPSubscription(PrefService* prefs)

AIChatIAPSubscription::~AIChatIAPSubscription() = default;

void AIChatIAPSubscription::GetPurchaseToken(
GetPurchaseTokenCallback callback) {
void AIChatIAPSubscription::GetPurchaseTokenOrderId(
GetPurchaseTokenOrderIdCallback callback) {
std::string order_id_string = "";
std::string purchase_token_string = "";
std::string package_string = kDefaultPackage;
std::string product_id_string = kProductId;
Expand All @@ -52,6 +53,11 @@ void AIChatIAPSubscription::GetPurchaseToken(
product_id_string = prefs_->GetString(prefs::kBraveChatProductIdAndroid);
}

auto* order_id = prefs_->FindPreference(prefs::kBraveChatOrderIdAndroid);
if (order_id && !product_id->IsDefaultValue()) {
order_id_string = prefs_->GetString(prefs::kBraveChatOrderIdAndroid);
}

base::Value::Dict response;
response.Set("type", "android");
response.Set("raw_receipt", purchase_token_string);
Expand All @@ -63,7 +69,7 @@ void AIChatIAPSubscription::GetPurchaseToken(

std::string encoded_response_json;
base::Base64Encode(response_json, &encoded_response_json);
std::move(callback).Run(encoded_response_json);
std::move(callback).Run(encoded_response_json, order_id_string);
}

} // namespace ai_chat
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ class AIChatIAPSubscription final : public ai_chat::mojom::IAPSubscription {
~AIChatIAPSubscription() override;

// ai_chat::mojom::IAPSubscription
void GetPurchaseToken(GetPurchaseTokenCallback callback) override;
void GetPurchaseTokenOrderId(
GetPurchaseTokenOrderIdCallback callback) override;

private:
raw_ptr<PrefService> prefs_ = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion components/ai_chat/core/common/mojom/ai_chat.mojom
Original file line number Diff line number Diff line change
Expand Up @@ -211,5 +211,5 @@ interface AIChatAndroidHelper {

[EnableIf=is_android]
interface IAPSubscription {
GetPurchaseToken() => (string token);
GetPurchaseTokenOrderId() => (string token, string order_id);
};
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ inline constexpr char kIntentParamTestValue[] = "connect-receipt-test";
inline constexpr char kProductParamName[] = "product";
inline constexpr char kProductVPNParamValue[] = "vpn";
inline constexpr char kProductLeoParamValue[] = "leo";
inline constexpr char kIntentParamValueLeo[] = "link-order";

} // namespace

Expand All @@ -61,8 +62,7 @@ bool SubscriptionRenderFrameObserver::EnsureConnected() {
}
#endif
#if BUILDFLAG(ENABLE_AI_CHAT)
if (ai_chat::features::IsAIChatHistoryEnabled() &&
product_ == Product::kLeo) {
if (ai_chat::features::IsAIChatEnabled() && product_ == Product::kLeo) {
if (!ai_chat_subscription_.is_bound()) {
render_frame()->GetBrowserInterfaceBroker()->GetInterface(
ai_chat_subscription_.BindNewPipeAndPassReceiver());
Expand Down Expand Up @@ -105,36 +105,59 @@ void SubscriptionRenderFrameObserver::DidCreateScriptContext(
} else if (product_ == Product::kLeo) {
#if BUILDFLAG(ENABLE_AI_CHAT)
if (ai_chat_subscription_.is_bound()) {
ai_chat_subscription_->GetPurchaseToken(
base::BindOnce(&SubscriptionRenderFrameObserver::OnGetPurchaseToken,
weak_factory_.GetWeakPtr()));
ai_chat_subscription_->GetPurchaseTokenOrderId(base::BindOnce(
&SubscriptionRenderFrameObserver::OnGetPurchaseTokenOrderId,
weak_factory_.GetWeakPtr()));
}
#endif
}
}

std::string SubscriptionRenderFrameObserver::GetPurchaseTokenJSString(
const std::string& purchase_token) {
if (!IsValueAllowed(purchase_token)) {
return "";
}

std::string_view receipt_var_name;
if (product_ == Product::kVPN) {
receipt_var_name = "braveVpn.receipt";
} else if (product_ == Product::kLeo) {
receipt_var_name = "braveLeo.receipt";
}

return base::StrCat({"window.localStorage.setItem(\"", receipt_var_name,
"\", \"", purchase_token, "\");"});
}

void SubscriptionRenderFrameObserver::OnGetPurchaseToken(
const std::string& purchase_token) {
if (!IsAllowed()) {
return;
}
auto* frame = render_frame();
if (frame) {
if (IsValueAllowed(purchase_token)) {
std::string_view receipt_var_name;
if (product_ == Product::kVPN) {
receipt_var_name = "braveVpn.receipt";
} else if (product_ == Product::kLeo) {
receipt_var_name = "braveLeo.receipt";
}
std::u16string set_local_storage = base::UTF8ToUTF16(
base::StrCat({"window.localStorage.setItem(\"", receipt_var_name,
"\", \"", purchase_token, "\");"}));
frame->ExecuteJavaScript(set_local_storage);
std::string set_local_storage = GetPurchaseTokenJSString(purchase_token);
if (!set_local_storage.empty()) {
frame->ExecuteJavaScript(base::UTF8ToUTF16(set_local_storage));
}
}
}

void SubscriptionRenderFrameObserver::OnGetPurchaseTokenOrderId(
const std::string& purchase_token,
const std::string& order_id) {
if (!IsAllowed()) {
return;
}
auto* frame = render_frame();
if (frame && !order_id.empty() && !purchase_token.empty()) {
frame->ExecuteJavaScript(base::UTF8ToUTF16(base::StrCat(
{"window.localStorage.setItem(\"braveLeo.orderId\", \"", order_id,
"\");", GetPurchaseTokenJSString(purchase_token)})));
}
}

std::string SubscriptionRenderFrameObserver::ExtractParam(
const GURL& url,
const std::string& name) const {
Expand Down Expand Up @@ -182,7 +205,8 @@ bool SubscriptionRenderFrameObserver::IsAllowed() {
} else {
product_ = std::nullopt;
}
return (intent == kIntentParamValue || intent == kIntentParamTestValue) &&
return (intent == kIntentParamValue || intent == kIntentParamTestValue ||
intent == kIntentParamValueLeo) &&
product_.has_value();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ class SubscriptionRenderFrameObserver : public content::RenderFrameObserver {

bool EnsureConnected();
void OnGetPurchaseToken(const std::string& purchase_token);
void OnGetPurchaseTokenOrderId(const std::string& purchase_token,
const std::string& order_id);
std::string ExtractParam(const GURL& url, const std::string& name) const;
bool IsValueAllowed(const std::string& purchase_token) const;

Expand All @@ -67,6 +69,8 @@ class SubscriptionRenderFrameObserver : public content::RenderFrameObserver {

bool IsAllowed();

std::string GetPurchaseTokenJSString(const std::string& purchase_token);

const int32_t world_id_;
std::optional<Product> product_ = std::nullopt;
#if BUILDFLAG(ENABLE_BRAVE_VPN)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ class SubscriptionRenderFrameObserverBrowserTest :
SubscriptionRenderFrameObserverBrowserTest() {
scoped_feature_list_.InitWithFeatures(
{skus::features::kSkusFeature, brave_vpn::features::kBraveVPN,
ai_chat::features::kAIChatHistory
}, {});
ai_chat::features::kAIChat},
{});
}
~SubscriptionRenderFrameObserverBrowserTest() override = default;

Expand All @@ -46,7 +46,7 @@ TEST_F(SubscriptionRenderFrameObserverBrowserTest, IsAllowed) {
// Leo
LoadHTMLWithUrlOverride(
R"(<html><body></body></html>)",
"https://account.brave.com/?intent=connect-receipt&product=leo");
"https://account.brave.com/?intent=link-order&product=leo");

EXPECT_TRUE(observer.IsAllowed());
// http
Expand Down