mirror of
https://github.com/AyuGram/AyuGramDesktop.git
synced 2025-06-05 06:33:57 +02:00
Add a warning once per bot on payment.
This commit is contained in:
parent
62684ab9bb
commit
e106bd143e
12 changed files with 123 additions and 18 deletions
|
@ -86,12 +86,12 @@ void BotGameUrlClickHandler::onClick(ClickContext context) const {
|
||||||
open();
|
open();
|
||||||
} else if (!_bot
|
} else if (!_bot
|
||||||
|| _bot->isVerified()
|
|| _bot->isVerified()
|
||||||
|| _bot->session().local().isBotTrusted(_bot)) {
|
|| _bot->session().local().isBotTrustedOpenGame(_bot->id)) {
|
||||||
open();
|
open();
|
||||||
} else {
|
} else {
|
||||||
const auto callback = [=, bot = _bot] {
|
const auto callback = [=, bot = _bot] {
|
||||||
Ui::hideLayer();
|
Ui::hideLayer();
|
||||||
bot->session().local().markBotTrusted(bot);
|
bot->session().local().markBotTrustedOpenGame(bot->id);
|
||||||
open();
|
open();
|
||||||
};
|
};
|
||||||
Ui::show(Box<ConfirmBox>(
|
Ui::show(Box<ConfirmBox>(
|
||||||
|
|
|
@ -166,6 +166,12 @@ void CheckoutProcess::handleFormUpdate(const FormUpdate &update) {
|
||||||
}, [&](const TmpPasswordRequired &) {
|
}, [&](const TmpPasswordRequired &) {
|
||||||
_submitState = SubmitState::Validated;
|
_submitState = SubmitState::Validated;
|
||||||
requestPassword();
|
requestPassword();
|
||||||
|
}, [&](const BotTrustRequired &data) {
|
||||||
|
_submitState = SubmitState::Validated;
|
||||||
|
_panel->showWarning(data.bot->name, data.provider->name);
|
||||||
|
if (const auto box = _enterPasswordBox.data()) {
|
||||||
|
box->closeBox();
|
||||||
|
}
|
||||||
}, [&](const VerificationNeeded &data) {
|
}, [&](const VerificationNeeded &data) {
|
||||||
auto bottomText = tr::lng_payments_processed_by(
|
auto bottomText = tr::lng_payments_processed_by(
|
||||||
lt_provider,
|
lt_provider,
|
||||||
|
@ -366,6 +372,11 @@ void CheckoutProcess::panelSubmit() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CheckoutProcess::panelTrustAndSubmit() {
|
||||||
|
_form->trustBot();
|
||||||
|
panelSubmit();
|
||||||
|
}
|
||||||
|
|
||||||
void CheckoutProcess::panelWebviewMessage(
|
void CheckoutProcess::panelWebviewMessage(
|
||||||
const QJsonDocument &message,
|
const QJsonDocument &message,
|
||||||
bool saveInformation) {
|
bool saveInformation) {
|
||||||
|
|
|
@ -87,7 +87,6 @@ private:
|
||||||
void editPaymentMethod();
|
void editPaymentMethod();
|
||||||
|
|
||||||
void requestSetPassword();
|
void requestSetPassword();
|
||||||
void requestSetPasswordSure(QPointer<Ui::GenericBox> old);
|
|
||||||
void requestPassword();
|
void requestPassword();
|
||||||
void getPasswordState(
|
void getPasswordState(
|
||||||
Fn<void(const Core::CloudPasswordState&)> callback);
|
Fn<void(const Core::CloudPasswordState&)> callback);
|
||||||
|
@ -97,6 +96,7 @@ private:
|
||||||
void panelRequestClose() override;
|
void panelRequestClose() override;
|
||||||
void panelCloseSure() override;
|
void panelCloseSure() override;
|
||||||
void panelSubmit() override;
|
void panelSubmit() override;
|
||||||
|
void panelTrustAndSubmit() override;
|
||||||
void panelWebviewMessage(
|
void panelWebviewMessage(
|
||||||
const QJsonDocument &message,
|
const QJsonDocument &message,
|
||||||
bool saveInformation) override;
|
bool saveInformation) override;
|
||||||
|
|
|
@ -21,6 +21,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#include "stripe/stripe_error.h"
|
#include "stripe/stripe_error.h"
|
||||||
#include "stripe/stripe_token.h"
|
#include "stripe/stripe_token.h"
|
||||||
#include "stripe/stripe_card_validator.h"
|
#include "stripe/stripe_card_validator.h"
|
||||||
|
#include "storage/storage_account.h"
|
||||||
#include "ui/image/image.h"
|
#include "ui/image/image.h"
|
||||||
#include "apiwrap.h"
|
#include "apiwrap.h"
|
||||||
#include "core/core_cloud_password.h"
|
#include "core/core_cloud_password.h"
|
||||||
|
@ -478,6 +479,12 @@ void Form::submit() {
|
||||||
if (!_paymentMethod.newCredentials && password.isEmpty()) {
|
if (!_paymentMethod.newCredentials && password.isEmpty()) {
|
||||||
_updates.fire(TmpPasswordRequired{});
|
_updates.fire(TmpPasswordRequired{});
|
||||||
return;
|
return;
|
||||||
|
} else if (!_session->local().isBotTrustedPayment(_details.botId)) {
|
||||||
|
_updates.fire(BotTrustRequired{
|
||||||
|
.bot = _session->data().user(_details.botId),
|
||||||
|
.provider = _session->data().user(_details.providerId),
|
||||||
|
});
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
using Flag = MTPpayments_SendPaymentForm::Flag;
|
using Flag = MTPpayments_SendPaymentForm::Flag;
|
||||||
|
@ -773,6 +780,10 @@ void Form::setTips(int64 value) {
|
||||||
_invoice.tipsSelected = std::min(value, _invoice.tipsMax);
|
_invoice.tipsSelected = std::min(value, _invoice.tipsMax);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Form::trustBot() {
|
||||||
|
_session->local().markBotTrustedPayment(_details.botId);
|
||||||
|
}
|
||||||
|
|
||||||
void Form::processShippingOptions(const QVector<MTPShippingOption> &data) {
|
void Form::processShippingOptions(const QVector<MTPShippingOption> &data) {
|
||||||
const auto currency = _invoice.currency;
|
const auto currency = _invoice.currency;
|
||||||
_shippingOptions = Ui::ShippingOptions{ currency, ranges::views::all(
|
_shippingOptions = Ui::ShippingOptions{ currency, ranges::views::all(
|
||||||
|
|
|
@ -118,6 +118,10 @@ struct VerificationNeeded {
|
||||||
QString url;
|
QString url;
|
||||||
};
|
};
|
||||||
struct TmpPasswordRequired {};
|
struct TmpPasswordRequired {};
|
||||||
|
struct BotTrustRequired {
|
||||||
|
not_null<UserData*> bot;
|
||||||
|
not_null<UserData*> provider;
|
||||||
|
};
|
||||||
struct PaymentFinished {
|
struct PaymentFinished {
|
||||||
MTPUpdates updates;
|
MTPUpdates updates;
|
||||||
};
|
};
|
||||||
|
@ -148,6 +152,7 @@ struct FormUpdate : std::variant<
|
||||||
PaymentMethodUpdate,
|
PaymentMethodUpdate,
|
||||||
VerificationNeeded,
|
VerificationNeeded,
|
||||||
TmpPasswordRequired,
|
TmpPasswordRequired,
|
||||||
|
BotTrustRequired,
|
||||||
PaymentFinished,
|
PaymentFinished,
|
||||||
Error> {
|
Error> {
|
||||||
using variant::variant;
|
using variant::variant;
|
||||||
|
@ -187,6 +192,7 @@ public:
|
||||||
void setHasPassword(bool has);
|
void setHasPassword(bool has);
|
||||||
void setShippingOption(const QString &id);
|
void setShippingOption(const QString &id);
|
||||||
void setTips(int64 value);
|
void setTips(int64 value);
|
||||||
|
void trustBot();
|
||||||
void submit();
|
void submit();
|
||||||
void submit(const Core::CloudPasswordResult &result);
|
void submit(const Core::CloudPasswordResult &result);
|
||||||
|
|
||||||
|
|
|
@ -79,6 +79,10 @@ paymentsIconPhone: icon {{ "payments/payment_phone", menuIconFg }};
|
||||||
paymentsIconShippingMethod: icon {{ "payments/payment_shipping", menuIconFg }};
|
paymentsIconShippingMethod: icon {{ "payments/payment_shipping", menuIconFg }};
|
||||||
|
|
||||||
paymentsField: defaultInputField;
|
paymentsField: defaultInputField;
|
||||||
|
paymentsMoneyField: InputField(paymentsField) {
|
||||||
|
textMargins: margins(0px, 4px, 0px, 4px);
|
||||||
|
heightMin: 30px;
|
||||||
|
}
|
||||||
paymentsFieldAdditional: FlatLabel(defaultFlatLabel) {
|
paymentsFieldAdditional: FlatLabel(defaultFlatLabel) {
|
||||||
style: boxTextStyle;
|
style: boxTextStyle;
|
||||||
}
|
}
|
||||||
|
|
|
@ -289,7 +289,7 @@ struct SimpleFieldState {
|
||||||
};
|
};
|
||||||
const auto state = wrap->lifetime().make_state<State>(State{
|
const auto state = wrap->lifetime().make_state<State>(State{
|
||||||
.rule = LookupCurrencyRule(config.currency),
|
.rule = LookupCurrencyRule(config.currency),
|
||||||
.st = st::paymentsField,
|
.st = st::paymentsMoneyField,
|
||||||
});
|
});
|
||||||
const auto &rule = state->rule;
|
const auto &rule = state->rule;
|
||||||
state->currencySkip = rule.space ? state->st.font->spacew : 0;
|
state->currencySkip = rule.space ? state->st.font->spacew : 0;
|
||||||
|
|
|
@ -409,6 +409,29 @@ void Panel::showCloseConfirm() {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Panel::showWarning(const QString &bot, const QString &provider) {
|
||||||
|
showBox(Box([=](not_null<GenericBox*> box) {
|
||||||
|
box->setTitle(tr::lng_payments_warning_title());
|
||||||
|
box->addRow(object_ptr<FlatLabel>(
|
||||||
|
box.get(),
|
||||||
|
tr::lng_payments_warning_body(
|
||||||
|
lt_bot1,
|
||||||
|
rpl::single(bot),
|
||||||
|
lt_provider,
|
||||||
|
rpl::single(provider),
|
||||||
|
lt_bot2,
|
||||||
|
rpl::single(bot),
|
||||||
|
lt_bot3,
|
||||||
|
rpl::single(bot)),
|
||||||
|
st::boxLabel));
|
||||||
|
box->addButton(tr::lng_continue(), [=] {
|
||||||
|
_delegate->panelTrustAndSubmit();
|
||||||
|
box->closeBox();
|
||||||
|
});
|
||||||
|
box->addButton(tr::lng_cancel(), [=] { box->closeBox(); });
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
void Panel::showEditCard(
|
void Panel::showEditCard(
|
||||||
const NativeMethodDetails &native,
|
const NativeMethodDetails &native,
|
||||||
CardField field) {
|
CardField field) {
|
||||||
|
|
|
@ -69,6 +69,7 @@ public:
|
||||||
void choosePaymentMethod(const PaymentMethodDetails &method);
|
void choosePaymentMethod(const PaymentMethodDetails &method);
|
||||||
void askSetPassword();
|
void askSetPassword();
|
||||||
void showCloseConfirm();
|
void showCloseConfirm();
|
||||||
|
void showWarning(const QString &bot, const QString &provider);
|
||||||
|
|
||||||
bool showWebview(
|
bool showWebview(
|
||||||
const QString &url,
|
const QString &url,
|
||||||
|
|
|
@ -28,6 +28,7 @@ public:
|
||||||
virtual void panelRequestClose() = 0;
|
virtual void panelRequestClose() = 0;
|
||||||
virtual void panelCloseSure() = 0;
|
virtual void panelCloseSure() = 0;
|
||||||
virtual void panelSubmit() = 0;
|
virtual void panelSubmit() = 0;
|
||||||
|
virtual void panelTrustAndSubmit() = 0;
|
||||||
virtual void panelWebviewMessage(
|
virtual void panelWebviewMessage(
|
||||||
const QJsonDocument &message,
|
const QJsonDocument &message,
|
||||||
bool saveInformation) = 0;
|
bool saveInformation) = 0;
|
||||||
|
|
|
@ -2509,8 +2509,12 @@ void Account::writeTrustedBots() {
|
||||||
quint32 size = sizeof(qint32) + _trustedBots.size() * sizeof(quint64);
|
quint32 size = sizeof(qint32) + _trustedBots.size() * sizeof(quint64);
|
||||||
EncryptedDescriptor data(size);
|
EncryptedDescriptor data(size);
|
||||||
data.stream << qint32(_trustedBots.size());
|
data.stream << qint32(_trustedBots.size());
|
||||||
for_const (auto botId, _trustedBots) {
|
for (const auto &[peerId, mask] : _trustedBots) {
|
||||||
data.stream << quint64(botId);
|
// value: 8 bit mask, 56 bit bot peer_id.
|
||||||
|
auto value = quint64(peerId);
|
||||||
|
Assert((value >> 56) == 0);
|
||||||
|
value |= (quint64(mask) << 56);
|
||||||
|
data.stream << value;
|
||||||
}
|
}
|
||||||
|
|
||||||
FileWriteDescriptor file(_trustedBotsKey, _basePath);
|
FileWriteDescriptor file(_trustedBotsKey, _basePath);
|
||||||
|
@ -2531,25 +2535,61 @@ void Account::readTrustedBots() {
|
||||||
qint32 size = 0;
|
qint32 size = 0;
|
||||||
trusted.stream >> size;
|
trusted.stream >> size;
|
||||||
for (int i = 0; i < size; ++i) {
|
for (int i = 0; i < size; ++i) {
|
||||||
quint64 botId = 0;
|
auto value = quint64();
|
||||||
trusted.stream >> botId;
|
trusted.stream >> value;
|
||||||
_trustedBots.insert(botId);
|
const auto mask = base::flags<BotTrustFlag>::from_raw(
|
||||||
|
uchar(value >> 56));
|
||||||
|
const auto peerId = value & ~(0xFFULL << 56);
|
||||||
|
_trustedBots.emplace(peerId, mask);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Account::markBotTrusted(not_null<UserData*> bot) {
|
void Account::markBotTrustedOpenGame(PeerId botId) {
|
||||||
if (!isBotTrusted(bot)) {
|
if (isBotTrustedOpenGame(botId)) {
|
||||||
_trustedBots.insert(bot->id);
|
return;
|
||||||
writeTrustedBots();
|
|
||||||
}
|
}
|
||||||
|
const auto i = _trustedBots.find(botId);
|
||||||
|
if (i == end(_trustedBots)) {
|
||||||
|
_trustedBots.emplace(botId, BotTrustFlag());
|
||||||
|
} else {
|
||||||
|
i->second &= ~BotTrustFlag::NoOpenGame;
|
||||||
|
}
|
||||||
|
writeTrustedBots();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Account::isBotTrusted(not_null<UserData*> bot) {
|
bool Account::isBotTrustedOpenGame(PeerId botId) {
|
||||||
if (!_trustedBotsRead) {
|
if (!_trustedBotsRead) {
|
||||||
readTrustedBots();
|
readTrustedBots();
|
||||||
_trustedBotsRead = true;
|
_trustedBotsRead = true;
|
||||||
}
|
}
|
||||||
return _trustedBots.contains(bot->id);
|
const auto i = _trustedBots.find(botId);
|
||||||
|
return (i != end(_trustedBots))
|
||||||
|
&& ((i->second & BotTrustFlag::NoOpenGame) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Account::markBotTrustedPayment(PeerId botId) {
|
||||||
|
if (isBotTrustedPayment(botId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const auto i = _trustedBots.find(botId);
|
||||||
|
if (i == end(_trustedBots)) {
|
||||||
|
_trustedBots.emplace(
|
||||||
|
botId,
|
||||||
|
BotTrustFlag::NoOpenGame | BotTrustFlag::Payment);
|
||||||
|
} else {
|
||||||
|
i->second |= BotTrustFlag::Payment;
|
||||||
|
}
|
||||||
|
writeTrustedBots();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Account::isBotTrustedPayment(PeerId botId) {
|
||||||
|
if (!_trustedBotsRead) {
|
||||||
|
readTrustedBots();
|
||||||
|
_trustedBotsRead = true;
|
||||||
|
}
|
||||||
|
const auto i = _trustedBots.find(botId);
|
||||||
|
return (i != end(_trustedBots))
|
||||||
|
&& ((i->second & BotTrustFlag::Payment) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Account::encrypt(
|
bool Account::encrypt(
|
||||||
|
|
|
@ -8,6 +8,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "base/timer.h"
|
#include "base/timer.h"
|
||||||
|
#include "base/flags.h"
|
||||||
#include "storage/cache/storage_cache_database.h"
|
#include "storage/cache/storage_cache_database.h"
|
||||||
#include "data/stickers/data_stickers_set.h"
|
#include "data/stickers/data_stickers_set.h"
|
||||||
#include "data/data_drafts.h"
|
#include "data/data_drafts.h"
|
||||||
|
@ -135,8 +136,10 @@ public:
|
||||||
const QByteArray& serialized,
|
const QByteArray& serialized,
|
||||||
int32 streamVersion);
|
int32 streamVersion);
|
||||||
|
|
||||||
void markBotTrusted(not_null<UserData*> bot);
|
void markBotTrustedOpenGame(PeerId botId);
|
||||||
[[nodiscard]] bool isBotTrusted(not_null<UserData*> bot);
|
[[nodiscard]] bool isBotTrustedOpenGame(PeerId botId);
|
||||||
|
void markBotTrustedPayment(PeerId botId);
|
||||||
|
[[nodiscard]] bool isBotTrustedPayment(PeerId botId);
|
||||||
|
|
||||||
[[nodiscard]] bool encrypt(
|
[[nodiscard]] bool encrypt(
|
||||||
const void *src,
|
const void *src,
|
||||||
|
@ -157,6 +160,11 @@ private:
|
||||||
IncorrectPasscode,
|
IncorrectPasscode,
|
||||||
Failed,
|
Failed,
|
||||||
};
|
};
|
||||||
|
enum class BotTrustFlag : uchar {
|
||||||
|
NoOpenGame = (1 << 0),
|
||||||
|
Payment = (1 << 1),
|
||||||
|
};
|
||||||
|
friend inline constexpr bool is_flag_type(BotTrustFlag) { return true; };
|
||||||
|
|
||||||
[[nodiscard]] base::flat_set<QString> collectGoodNames() const;
|
[[nodiscard]] base::flat_set<QString> collectGoodNames() const;
|
||||||
[[nodiscard]] auto prepareReadSettingsContext() const
|
[[nodiscard]] auto prepareReadSettingsContext() const
|
||||||
|
@ -253,7 +261,7 @@ private:
|
||||||
qint32 _cacheTotalTimeLimit = 0;
|
qint32 _cacheTotalTimeLimit = 0;
|
||||||
qint32 _cacheBigFileTotalTimeLimit = 0;
|
qint32 _cacheBigFileTotalTimeLimit = 0;
|
||||||
|
|
||||||
base::flat_set<uint64> _trustedBots;
|
base::flat_map<PeerId, base::flags<BotTrustFlag>> _trustedBots;
|
||||||
bool _trustedBotsRead = false;
|
bool _trustedBotsRead = false;
|
||||||
bool _readingUserSettings = false;
|
bool _readingUserSettings = false;
|
||||||
bool _recentHashtagsAndBotsWereRead = false;
|
bool _recentHashtagsAndBotsWereRead = false;
|
||||||
|
|
Loading…
Add table
Reference in a new issue