diff options
Diffstat (limited to 'src/remoteauth')
-rw-r--r-- | src/remoteauth/remoteauthclient.cpp | 38 | ||||
-rw-r--r-- | src/remoteauth/remoteauthclient.hpp | 12 | ||||
-rw-r--r-- | src/remoteauth/remoteauthdialog.cpp | 45 | ||||
-rw-r--r-- | src/remoteauth/remoteauthdialog.hpp | 5 |
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; }; |