summaryrefslogtreecommitdiff
path: root/src/remoteauth
diff options
context:
space:
mode:
authorouwou <26526779+ouwou@users.noreply.github.com>2023-07-01 02:10:42 -0400
committerouwou <26526779+ouwou@users.noreply.github.com>2023-07-01 02:10:42 -0400
commitab448a3a9820663a882bde242525546cc4273516 (patch)
treeb55ee697969427d404ccae2ce83c8f684c3602ed /src/remoteauth
parent044e508df7868856648e14ad7c957be8b9bb46b5 (diff)
downloadabaddon-portaudio-ab448a3a9820663a882bde242525546cc4273516.tar.gz
abaddon-portaudio-ab448a3a9820663a882bde242525546cc4273516.zip
show status, error when captcha required
Diffstat (limited to 'src/remoteauth')
-rw-r--r--src/remoteauth/remoteauthclient.cpp38
-rw-r--r--src/remoteauth/remoteauthclient.hpp12
-rw-r--r--src/remoteauth/remoteauthdialog.cpp45
-rw-r--r--src/remoteauth/remoteauthdialog.hpp5
4 files changed, 98 insertions, 2 deletions
diff --git a/src/remoteauth/remoteauthclient.cpp b/src/remoteauth/remoteauthclient.cpp
index 5749f10..e2d3cc6 100644
--- a/src/remoteauth/remoteauthclient.cpp
+++ b/src/remoteauth/remoteauthclient.cpp
@@ -68,6 +68,8 @@ void RemoteAuthClient::HandleGatewayHello(const nlohmann::json &j) {
m_heartbeat_thread = std::thread(&RemoteAuthClient::HeartbeatThread, this);
Init();
+
+ m_signal_hello.emit();
}
void RemoteAuthClient::HandleGatewayNonceProof(const nlohmann::json &j) {
@@ -98,15 +100,35 @@ void RemoteAuthClient::HandleGatewayPendingTicket(const nlohmann::json &j) {
const auto payload = Decrypt(reinterpret_cast<const unsigned char *>(encrypted_payload.data()), encrypted_payload.size());
m_log->trace("User payload: {}", std::string(payload.begin(), payload.end()));
+
+ const std::vector<Glib::ustring> user_info = Glib::Regex::split_simple(":", std::string(payload.begin(), payload.end()));
+ Snowflake user_id;
+ std::string discriminator;
+ std::string avatar_hash;
+ std::string username;
+ if (user_info.size() >= 4) {
+ user_id = Snowflake(user_info[0]);
+ discriminator = user_info[1];
+ avatar_hash = user_info[2];
+ username = user_info[3];
+ }
+
+ m_signal_pending_ticket.emit(user_id, discriminator, avatar_hash, username);
}
void RemoteAuthClient::HandleGatewayPendingLogin(const nlohmann::json &j) {
Abaddon::Get().GetDiscordClient().RemoteAuthLogin(j.at("ticket").get<std::string>(), sigc::mem_fun(*this, &RemoteAuthClient::OnRemoteAuthLoginResponse));
+ m_signal_pending_login.emit();
}
void RemoteAuthClient::OnRemoteAuthLoginResponse(const std::optional<std::string> &encrypted_token, DiscordError err) {
if (!encrypted_token.has_value()) {
m_log->error("Remote auth login failed: {}", static_cast<int>(err));
+ if (err == DiscordError::CAPTCHA_REQUIRED) {
+ m_signal_error.emit("Discord is requiring a captcha. You must use a web browser to log in.");
+ } else {
+ m_signal_error.emit("An error occurred. Try again.");
+ }
return;
}
@@ -272,10 +294,26 @@ void RemoteAuthClient::OnDispatch() {
OnGatewayMessage(msg);
}
+RemoteAuthClient::type_signal_hello RemoteAuthClient::signal_hello() {
+ return m_signal_hello;
+}
+
RemoteAuthClient::type_signal_fingerprint RemoteAuthClient::signal_fingerprint() {
return m_signal_fingerprint;
}
+RemoteAuthClient::type_signal_pending_ticket RemoteAuthClient::signal_pending_ticket() {
+ return m_signal_pending_ticket;
+}
+
+RemoteAuthClient::type_signal_pending_login RemoteAuthClient::signal_pending_login() {
+ return m_signal_pending_login;
+}
+
RemoteAuthClient::type_signal_token RemoteAuthClient::signal_token() {
return m_signal_token;
}
+
+RemoteAuthClient::type_signal_error RemoteAuthClient::signal_error() {
+ return m_signal_error;
+}
diff --git a/src/remoteauth/remoteauthclient.hpp b/src/remoteauth/remoteauthclient.hpp
index 8fb8bc3..7d7dee9 100644
--- a/src/remoteauth/remoteauthclient.hpp
+++ b/src/remoteauth/remoteauthclient.hpp
@@ -59,12 +59,24 @@ private:
EVP_PKEY_ptr m_pkey;
public:
+ using type_signal_hello = sigc::signal<void()>;
using type_signal_fingerprint = sigc::signal<void(std::string)>;
+ using type_signal_pending_ticket = sigc::signal<void(Snowflake, std::string, std::string, std::string)>;
+ using type_signal_pending_login = sigc::signal<void()>;
using type_signal_token = sigc::signal<void(std::string)>;
+ using type_signal_error = sigc::signal<void(std::string)>;
+ type_signal_hello signal_hello();
type_signal_fingerprint signal_fingerprint();
+ type_signal_pending_ticket signal_pending_ticket();
+ type_signal_pending_login signal_pending_login();
type_signal_token signal_token();
+ type_signal_error signal_error();
private:
+ type_signal_hello m_signal_hello;
type_signal_fingerprint m_signal_fingerprint;
+ type_signal_pending_ticket m_signal_pending_ticket;
+ type_signal_pending_login m_signal_pending_login;
type_signal_token m_signal_token;
+ type_signal_error m_signal_error;
};
diff --git a/src/remoteauth/remoteauthdialog.cpp b/src/remoteauth/remoteauthdialog.cpp
index ea250d6..c59f0ed 100644
--- a/src/remoteauth/remoteauthdialog.cpp
+++ b/src/remoteauth/remoteauthdialog.cpp
@@ -23,21 +23,40 @@ RemoteAuthDialog::RemoteAuthDialog(Gtk::Window &parent)
m_bbox.pack_start(m_cancel, Gtk::PACK_SHRINK);
m_bbox.set_layout(Gtk::BUTTONBOX_END);
+ m_ra.signal_hello().connect(sigc::mem_fun(*this, &RemoteAuthDialog::OnHello));
m_ra.signal_fingerprint().connect(sigc::mem_fun(*this, &RemoteAuthDialog::OnFingerprint));
+ m_ra.signal_pending_ticket().connect(sigc::mem_fun(*this, &RemoteAuthDialog::OnPendingTicket));
+ m_ra.signal_pending_login().connect(sigc::mem_fun(*this, &RemoteAuthDialog::OnPendingLogin));
m_ra.signal_token().connect(sigc::mem_fun(*this, &RemoteAuthDialog::OnToken));
+ m_ra.signal_error().connect(sigc::mem_fun(*this, &RemoteAuthDialog::OnError));
m_ra.Start();
m_image.set_size_request(256, 256);
+ m_status.set_text("Connecting...");
+ m_status.set_hexpand(true);
+ m_status.set_halign(Gtk::ALIGN_CENTER);
+
m_layout.add(m_image);
+ m_layout.add(m_status);
m_layout.add(m_bbox);
get_content_area()->add(m_layout);
show_all_children();
}
+std::string RemoteAuthDialog::GetToken() {
+ return m_token;
+}
+
+void RemoteAuthDialog::OnHello() {
+ m_status.set_text("Handshaking...");
+}
+
void RemoteAuthDialog::OnFingerprint(const std::string &fingerprint) {
+ m_status.set_text("Waiting for mobile device...");
+
const auto url = "https://discord.com/ra/" + fingerprint;
const auto level = qrcodegen::QrCode::Ecc::QUARTILE;
@@ -75,8 +94,24 @@ void RemoteAuthDialog::OnFingerprint(const std::string &fingerprint) {
m_image.property_pixbuf() = pb;
}
-std::string RemoteAuthDialog::GetToken() {
- return m_token;
+void RemoteAuthDialog::OnPendingTicket(Snowflake user_id, std::string discriminator, std::string avatar_hash, std::string username) {
+ Glib::ustring name = username;
+ if (discriminator != "0") {
+ name += "#" + discriminator;
+ }
+ m_status.set_text("Waiting for confirmation... (" + name + ")");
+
+ if (!avatar_hash.empty()) {
+ const auto url = "https://cdn.discordapp.com/avatars/" + std::to_string(user_id) + "/" + avatar_hash + ".png?size=256";
+ const auto cb = [this](const Glib::RefPtr<Gdk::Pixbuf> &pb) {
+ m_image.property_pixbuf() = pb->scale_simple(256, 256, Gdk::INTERP_BILINEAR);
+ };
+ Abaddon::Get().GetImageManager().LoadFromURL(url, sigc::track_obj(cb, *this));
+ }
+}
+
+void RemoteAuthDialog::OnPendingLogin() {
+ m_status.set_text("Logging in!");
}
void RemoteAuthDialog::OnToken(const std::string &token) {
@@ -84,3 +119,9 @@ void RemoteAuthDialog::OnToken(const std::string &token) {
m_ra.Stop();
response(Gtk::RESPONSE_OK);
}
+
+void RemoteAuthDialog::OnError(const std::string &error) {
+ m_ra.Stop();
+ Abaddon::Get().ShowConfirm(error, dynamic_cast<Gtk::Window*>(get_toplevel()));
+ response(Gtk::RESPONSE_CANCEL);
+}
diff --git a/src/remoteauth/remoteauthdialog.hpp b/src/remoteauth/remoteauthdialog.hpp
index 44af821..be559df 100644
--- a/src/remoteauth/remoteauthdialog.hpp
+++ b/src/remoteauth/remoteauthdialog.hpp
@@ -9,6 +9,7 @@ public:
protected:
Gtk::Image m_image;
+ Gtk::Label m_status;
Gtk::Box m_layout;
Gtk::Button m_ok;
Gtk::Button m_cancel;
@@ -17,8 +18,12 @@ protected:
private:
RemoteAuthClient m_ra;
+ void OnHello();
void OnFingerprint(const std::string &fingerprint);
+ void OnPendingTicket(Snowflake user_id, std::string discriminator, std::string avatar_hash, std::string username);
+ void OnPendingLogin();
void OnToken(const std::string &token);
+ void OnError(const std::string &error);
std::string m_token;
};