From 3b206e11216b383fae0e860e0092f71301fd4425 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Fri, 30 Jun 2023 20:43:08 -0400 Subject: remote auth impl. up to QR code display --- src/remoteauth/remoteauthclient.hpp | 64 +++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 src/remoteauth/remoteauthclient.hpp (limited to 'src/remoteauth/remoteauthclient.hpp') diff --git a/src/remoteauth/remoteauthclient.hpp b/src/remoteauth/remoteauthclient.hpp new file mode 100644 index 0000000..178e10a --- /dev/null +++ b/src/remoteauth/remoteauthclient.hpp @@ -0,0 +1,64 @@ +#pragma once +#include +#include +#include +#include "ssl.hpp" +#include "discord/waiter.hpp" +#include "discord/websocket.hpp" + +class RemoteAuthClient { +public: + RemoteAuthClient(); + ~RemoteAuthClient(); + + void Start(); + void Stop(); + + [[nodiscard]] bool IsConnected() const noexcept; + +private: + void OnGatewayMessage(const std::string &str); + void HandleGatewayHello(const nlohmann::json &j); + void HandleGatewayNonceProof(const nlohmann::json &j); + void HandleGatewayPendingRemoteInit(const nlohmann::json &j); + void HandleGatewayPendingTicket(const nlohmann::json &j); + + void Init(); + + void GenerateKey(); + std::string GetEncodedPublicKey() const; + + std::vector Decrypt(const unsigned char *in, size_t inlen) const; + + void OnWebsocketOpen(); + void OnWebsocketClose(const ix::WebSocketCloseInfo &info); + void OnWebsocketMessage(const std::string &str); + + void HeartbeatThread(); + + int m_heartbeat_msec; + Waiter m_heartbeat_waiter; + std::thread m_heartbeat_thread; + + Glib::Dispatcher m_dispatcher; + std::queue m_dispatch_queue; + std::mutex m_dispatch_mutex; + + void OnDispatch(); + + Websocket m_ws; + bool m_connected = false; + + std::shared_ptr m_log; + + EVP_PKEY_CTX_ptr m_pkey_ctx; + EVP_PKEY_CTX_ptr m_dec_ctx; + EVP_PKEY_ptr m_pkey; + +public: + using type_signal_fingerprint = sigc::signal; + type_signal_fingerprint signal_fingerprint(); + +private: + type_signal_fingerprint m_signal_fingerprint; +}; -- cgit v1.2.3 From 4ac7ca9245016616bbc77acf8e989e41729e1afd Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sat, 1 Jul 2023 00:56:09 -0400 Subject: finalize login --- src/abaddon.cpp | 3 +++ src/discord/discord.cpp | 14 ++++++++++++++ src/discord/discord.hpp | 2 ++ src/remoteauth/remoteauthclient.cpp | 32 ++++++++++++++++++++++++++++++++ src/remoteauth/remoteauthclient.hpp | 6 ++++++ src/remoteauth/remoteauthdialog.cpp | 7 +++++++ src/remoteauth/remoteauthdialog.hpp | 1 + 7 files changed, 65 insertions(+) (limited to 'src/remoteauth/remoteauthclient.hpp') diff --git a/src/abaddon.cpp b/src/abaddon.cpp index 545a3c2..e0d39b5 100644 --- a/src/abaddon.cpp +++ b/src/abaddon.cpp @@ -841,9 +841,12 @@ void Abaddon::ActionLoginQR() { auto response = dlg.run(); if (response == Gtk::RESPONSE_OK) { m_discord_token = dlg.GetToken(); + m_discord.UpdateToken(m_discord_token); m_main_window->UpdateComponents(); + GetSettings().DiscordToken = m_discord_token; } m_main_window->UpdateMenus(); + ActionConnect(); } void Abaddon::ActionChannelOpened(Snowflake id, bool expand_to) { diff --git a/src/discord/discord.cpp b/src/discord/discord.cpp index 817aca8..5dc0464 100644 --- a/src/discord/discord.cpp +++ b/src/discord/discord.cpp @@ -1197,6 +1197,20 @@ void DiscordClient::AcceptVerificationGate(Snowflake guild_id, VerificationGateI }); } +void DiscordClient::RemoteAuthLogin(const std::string &ticket, const sigc::slot, DiscordError code)> &callback) { + http::request req(http::REQUEST_POST, "https://discord.com/api/v9/users/@me/remote-auth/login"); + req.set_header("Content-Type", "application/json"); + req.set_user_agent(Abaddon::Get().GetSettings().UserAgent); + req.set_body("{\"ticket\":\"" + ticket + "\"}"); + m_http.Execute(std::move(req), [this, callback](const http::response_type &r) { + if (CheckCode(r)) { + callback(nlohmann::json::parse(r.text).at("encrypted_token").get(), DiscordError::NONE); + } else { + callback(std::nullopt, GetCodeFromResponse(r)); + } + }); +} + #ifdef WITH_VOICE void DiscordClient::ConnectToVoice(Snowflake channel_id) { auto channel = GetChannel(channel_id); diff --git a/src/discord/discord.hpp b/src/discord/discord.hpp index d2435dd..438e4e6 100644 --- a/src/discord/discord.hpp +++ b/src/discord/discord.hpp @@ -184,6 +184,8 @@ public: void GetVerificationGateInfo(Snowflake guild_id, const sigc::slot)> &callback); void AcceptVerificationGate(Snowflake guild_id, VerificationGateInfoObject info, const sigc::slot &callback); + void RemoteAuthLogin(const std::string &ticket, const sigc::slot, DiscordError code)> &callback); + #ifdef WITH_VOICE void ConnectToVoice(Snowflake channel_id); void DisconnectFromVoice(); diff --git a/src/remoteauth/remoteauthclient.cpp b/src/remoteauth/remoteauthclient.cpp index 1ebb7cb..390f42d 100644 --- a/src/remoteauth/remoteauthclient.cpp +++ b/src/remoteauth/remoteauthclient.cpp @@ -1,4 +1,5 @@ #include "remoteauthclient.hpp" +#include "http.hpp" #include #include @@ -65,6 +66,14 @@ struct RemoteAuthPendingTicketMessage { } }; +struct RemoteAuthPendingLoginMessage { + std::string Ticket; + + friend void from_json(const nlohmann::json &j, RemoteAuthPendingLoginMessage &m) { + j.at("ticket").get_to(m.Ticket); + } +}; + RemoteAuthClient::RemoteAuthClient() : m_ws("remote-auth-ws") , m_log(spdlog::get("remote-auth")) { @@ -116,6 +125,8 @@ void RemoteAuthClient::OnGatewayMessage(const std::string &str) { HandleGatewayPendingRemoteInit(j); } else if (msg.Opcode == "pending_ticket") { HandleGatewayPendingTicket(j); + } else if (msg.Opcode == "pending_login") { + HandleGatewayPendingLogin(j); } } @@ -162,6 +173,23 @@ void RemoteAuthClient::HandleGatewayPendingTicket(const nlohmann::json &j) { m_log->trace("User payload: {}", std::string(payload.begin(), payload.end())); } +void RemoteAuthClient::HandleGatewayPendingLogin(const nlohmann::json &j) { + RemoteAuthPendingLoginMessage msg = j; + + Abaddon::Get().GetDiscordClient().RemoteAuthLogin(msg.Ticket, sigc::mem_fun(*this, &RemoteAuthClient::OnRemoteAuthLoginResponse)); +} + +void RemoteAuthClient::OnRemoteAuthLoginResponse(const std::optional &encrypted_token, DiscordError err) { + if (!encrypted_token.has_value()) { + m_log->error("Remote auth login failed: {}", static_cast(err)); + return; + } + + const auto encrypted = Glib::Base64::decode(*encrypted_token); + const auto token = Decrypt(reinterpret_cast(encrypted.data()), encrypted.size()); + m_signal_token.emit(std::string(token.begin(), token.end())); +} + void RemoteAuthClient::Init() { RemoteAuthInitMessage msg; @@ -319,3 +347,7 @@ void RemoteAuthClient::OnDispatch() { RemoteAuthClient::type_signal_fingerprint RemoteAuthClient::signal_fingerprint() { return m_signal_fingerprint; } + +RemoteAuthClient::type_signal_token RemoteAuthClient::signal_token() { + return m_signal_token; +} diff --git a/src/remoteauth/remoteauthclient.hpp b/src/remoteauth/remoteauthclient.hpp index 178e10a..8fb8bc3 100644 --- a/src/remoteauth/remoteauthclient.hpp +++ b/src/remoteauth/remoteauthclient.hpp @@ -22,6 +22,9 @@ private: void HandleGatewayNonceProof(const nlohmann::json &j); void HandleGatewayPendingRemoteInit(const nlohmann::json &j); void HandleGatewayPendingTicket(const nlohmann::json &j); + void HandleGatewayPendingLogin(const nlohmann::json &j); + + void OnRemoteAuthLoginResponse(const std::optional &encrypted_token, DiscordError err); void Init(); @@ -57,8 +60,11 @@ private: public: using type_signal_fingerprint = sigc::signal; + using type_signal_token = sigc::signal; type_signal_fingerprint signal_fingerprint(); + type_signal_token signal_token(); private: type_signal_fingerprint m_signal_fingerprint; + type_signal_token m_signal_token; }; diff --git a/src/remoteauth/remoteauthdialog.cpp b/src/remoteauth/remoteauthdialog.cpp index db154c4..ea250d6 100644 --- a/src/remoteauth/remoteauthdialog.cpp +++ b/src/remoteauth/remoteauthdialog.cpp @@ -24,6 +24,7 @@ RemoteAuthDialog::RemoteAuthDialog(Gtk::Window &parent) m_bbox.set_layout(Gtk::BUTTONBOX_END); m_ra.signal_fingerprint().connect(sigc::mem_fun(*this, &RemoteAuthDialog::OnFingerprint)); + m_ra.signal_token().connect(sigc::mem_fun(*this, &RemoteAuthDialog::OnToken)); m_ra.Start(); @@ -77,3 +78,9 @@ void RemoteAuthDialog::OnFingerprint(const std::string &fingerprint) { std::string RemoteAuthDialog::GetToken() { return m_token; } + +void RemoteAuthDialog::OnToken(const std::string &token) { + m_token = token; + m_ra.Stop(); + response(Gtk::RESPONSE_OK); +} diff --git a/src/remoteauth/remoteauthdialog.hpp b/src/remoteauth/remoteauthdialog.hpp index 24fad56..44af821 100644 --- a/src/remoteauth/remoteauthdialog.hpp +++ b/src/remoteauth/remoteauthdialog.hpp @@ -18,6 +18,7 @@ private: RemoteAuthClient m_ra; void OnFingerprint(const std::string &fingerprint); + void OnToken(const std::string &token); std::string m_token; }; -- cgit v1.2.3 From ab448a3a9820663a882bde242525546cc4273516 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sat, 1 Jul 2023 02:10:42 -0400 Subject: show status, error when captcha required --- src/discord/discord.cpp | 7 ++++++ src/discord/errors.hpp | 1 + src/remoteauth/remoteauthclient.cpp | 38 +++++++++++++++++++++++++++++++ src/remoteauth/remoteauthclient.hpp | 12 ++++++++++ src/remoteauth/remoteauthdialog.cpp | 45 +++++++++++++++++++++++++++++++++++-- src/remoteauth/remoteauthdialog.hpp | 5 +++++ 6 files changed, 106 insertions(+), 2 deletions(-) (limited to 'src/remoteauth/remoteauthclient.hpp') diff --git a/src/discord/discord.cpp b/src/discord/discord.cpp index 5dc0464..75d066b 100644 --- a/src/discord/discord.cpp +++ b/src/discord/discord.cpp @@ -1206,6 +1206,13 @@ void DiscordClient::RemoteAuthLogin(const std::string &ticket, const sigc::slot< if (CheckCode(r)) { callback(nlohmann::json::parse(r.text).at("encrypted_token").get(), DiscordError::NONE); } else { + try { + const auto j = nlohmann::json::parse(r.text); + if (j.contains("captcha_service")) { + callback(std::nullopt, DiscordError::CAPTCHA_REQUIRED); + return; + } + } catch (...) {} callback(std::nullopt, GetCodeFromResponse(r)); } }); diff --git a/src/discord/errors.hpp b/src/discord/errors.hpp index 4579563..8ead4f2 100644 --- a/src/discord/errors.hpp +++ b/src/discord/errors.hpp @@ -11,6 +11,7 @@ enum class DiscordError { RELATIONSHIP_ALREADY_FRIENDS = 80007, NONE = -1, + CAPTCHA_REQUIRED = -2, }; constexpr const char *GetDiscordErrorDisplayString(DiscordError error) { 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(encrypted_payload.data()), encrypted_payload.size()); m_log->trace("User payload: {}", std::string(payload.begin(), payload.end())); + + const std::vector 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(), sigc::mem_fun(*this, &RemoteAuthClient::OnRemoteAuthLoginResponse)); + m_signal_pending_login.emit(); } void RemoteAuthClient::OnRemoteAuthLoginResponse(const std::optional &encrypted_token, DiscordError err) { if (!encrypted_token.has_value()) { m_log->error("Remote auth login failed: {}", static_cast(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; using type_signal_fingerprint = sigc::signal; + using type_signal_pending_ticket = sigc::signal; + using type_signal_pending_login = sigc::signal; using type_signal_token = sigc::signal; + using type_signal_error = sigc::signal; + 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 &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(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; }; -- cgit v1.2.3 From aaa219ce27561bfe060bee5a4eaba0326bc50412 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sun, 9 Jul 2023 21:21:29 -0400 Subject: restart ra ws on timeout --- src/remoteauth/remoteauthclient.cpp | 11 +++++++++++ src/remoteauth/remoteauthclient.hpp | 3 +++ src/remoteauth/remoteauthdialog.cpp | 4 ++-- src/remoteauth/remoteauthdialog.hpp | 2 +- 4 files changed, 17 insertions(+), 3 deletions(-) (limited to 'src/remoteauth/remoteauthclient.hpp') diff --git a/src/remoteauth/remoteauthclient.cpp b/src/remoteauth/remoteauthclient.cpp index c0a06d9..083bdaa 100644 --- a/src/remoteauth/remoteauthclient.cpp +++ b/src/remoteauth/remoteauthclient.cpp @@ -34,6 +34,7 @@ void RemoteAuthClient::Stop() { } m_connected = false; + if (m_timeout_conn) m_timeout_conn.disconnect(); m_ws.Stop(1000); m_heartbeat_waiter.kill(); if (m_heartbeat_thread.joinable()) m_heartbeat_thread.join(); @@ -44,6 +45,7 @@ bool RemoteAuthClient::IsConnected() const noexcept { } void RemoteAuthClient::OnGatewayMessage(const std::string &str) { + m_log->trace(str); auto j = nlohmann::json::parse(str); const auto opcode = j.at("op").get(); if (opcode == "hello") { @@ -67,6 +69,8 @@ void RemoteAuthClient::HandleGatewayHello(const nlohmann::json &j) { m_heartbeat_msec = heartbeat_interval; m_heartbeat_thread = std::thread(&RemoteAuthClient::HeartbeatThread, this); + m_timeout_conn = Glib::signal_timeout().connect(sigc::mem_fun(*this, &RemoteAuthClient::OnTimeout), timeout_ms); + Init(); m_signal_hello.emit(); @@ -294,6 +298,13 @@ void RemoteAuthClient::OnDispatch() { OnGatewayMessage(msg); } +bool RemoteAuthClient::OnTimeout() { + m_log->trace("Socket timeout"); + Stop(); + Start(); + return false; // disconnect +} + RemoteAuthClient::type_signal_hello RemoteAuthClient::signal_hello() { return m_signal_hello; } diff --git a/src/remoteauth/remoteauthclient.hpp b/src/remoteauth/remoteauthclient.hpp index 7d7dee9..36f224a 100644 --- a/src/remoteauth/remoteauthclient.hpp +++ b/src/remoteauth/remoteauthclient.hpp @@ -49,6 +49,9 @@ private: void OnDispatch(); + bool OnTimeout(); + sigc::connection m_timeout_conn; + Websocket m_ws; bool m_connected = false; diff --git a/src/remoteauth/remoteauthdialog.cpp b/src/remoteauth/remoteauthdialog.cpp index 5ba91ae..547eb39 100644 --- a/src/remoteauth/remoteauthdialog.cpp +++ b/src/remoteauth/remoteauthdialog.cpp @@ -91,7 +91,7 @@ void RemoteAuthDialog::OnFingerprint(const std::string &fingerprint) { m_image.property_pixbuf() = pb; } -void RemoteAuthDialog::OnPendingTicket(Snowflake user_id, std::string discriminator, std::string avatar_hash, std::string username) { +void RemoteAuthDialog::OnPendingTicket(Snowflake user_id, const std::string &discriminator, const std::string &avatar_hash, const std::string &username) { Glib::ustring name = username; if (discriminator != "0") { name += "#" + discriminator; @@ -119,6 +119,6 @@ void RemoteAuthDialog::OnToken(const std::string &token) { void RemoteAuthDialog::OnError(const std::string &error) { m_ra.Stop(); - Abaddon::Get().ShowConfirm(error, dynamic_cast(get_toplevel())); + Abaddon::Get().ShowConfirm(error, dynamic_cast(get_toplevel())); response(Gtk::RESPONSE_CANCEL); } diff --git a/src/remoteauth/remoteauthdialog.hpp b/src/remoteauth/remoteauthdialog.hpp index be559df..9a6ca29 100644 --- a/src/remoteauth/remoteauthdialog.hpp +++ b/src/remoteauth/remoteauthdialog.hpp @@ -20,7 +20,7 @@ private: void OnHello(); void OnFingerprint(const std::string &fingerprint); - void OnPendingTicket(Snowflake user_id, std::string discriminator, std::string avatar_hash, std::string username); + void OnPendingTicket(Snowflake user_id, const std::string &discriminator, const std::string &avatar_hash, const std::string &username); void OnPendingLogin(); void OnToken(const std::string &token); void OnError(const std::string &error); -- cgit v1.2.3 From 2ca5a21ab4a5c03ea8c8a584ca832d01d8661691 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sun, 9 Jul 2023 21:49:15 -0400 Subject: restart remote auth on cancel opcode --- src/remoteauth/remoteauthclient.cpp | 7 +++++++ src/remoteauth/remoteauthclient.hpp | 1 + 2 files changed, 8 insertions(+) (limited to 'src/remoteauth/remoteauthclient.hpp') diff --git a/src/remoteauth/remoteauthclient.cpp b/src/remoteauth/remoteauthclient.cpp index 7f41d71..467ea8b 100644 --- a/src/remoteauth/remoteauthclient.cpp +++ b/src/remoteauth/remoteauthclient.cpp @@ -58,6 +58,8 @@ void RemoteAuthClient::OnGatewayMessage(const std::string &str) { HandleGatewayPendingTicket(j); } else if (opcode == "pending_login") { HandleGatewayPendingLogin(j); + } else if (opcode == "cancel") { + HandleGatewayCancel(j); } } @@ -125,6 +127,11 @@ void RemoteAuthClient::HandleGatewayPendingLogin(const nlohmann::json &j) { m_signal_pending_login.emit(); } +void RemoteAuthClient::HandleGatewayCancel(const nlohmann::json &j) { + Stop(); + Start(); +} + void RemoteAuthClient::OnRemoteAuthLoginResponse(const std::optional &encrypted_token, DiscordError err) { if (!encrypted_token.has_value()) { m_log->error("Remote auth login failed: {}", static_cast(err)); diff --git a/src/remoteauth/remoteauthclient.hpp b/src/remoteauth/remoteauthclient.hpp index 36f224a..c2e00f3 100644 --- a/src/remoteauth/remoteauthclient.hpp +++ b/src/remoteauth/remoteauthclient.hpp @@ -23,6 +23,7 @@ private: void HandleGatewayPendingRemoteInit(const nlohmann::json &j); void HandleGatewayPendingTicket(const nlohmann::json &j); void HandleGatewayPendingLogin(const nlohmann::json &j); + void HandleGatewayCancel(const nlohmann::json &j); void OnRemoteAuthLoginResponse(const std::optional &encrypted_token, DiscordError err); -- cgit v1.2.3 From 229555939d697700e988f09f04871bde55adc5a7 Mon Sep 17 00:00:00 2001 From: ouwou <26526779+ouwou@users.noreply.github.com> Date: Sun, 9 Jul 2023 22:31:21 -0400 Subject: make qrcodegen optional wow!!! --- CMakeLists.txt | 12 ++++++++---- src/abaddon.cpp | 2 ++ src/remoteauth/remoteauthclient.cpp | 8 ++++++++ src/remoteauth/remoteauthclient.hpp | 9 +++++++++ src/remoteauth/remoteauthdialog.cpp | 8 ++++++++ src/remoteauth/remoteauthdialog.hpp | 9 +++++++++ src/windows/mainwindow.cpp | 6 ++++++ 7 files changed, 50 insertions(+), 4 deletions(-) (limited to 'src/remoteauth/remoteauthclient.hpp') diff --git a/CMakeLists.txt b/CMakeLists.txt index b85e6c1..7a782ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ option(USE_LIBHANDY "Enable features that require libhandy (default)" ON) option(ENABLE_VOICE "Enable voice suppport" ON) option(USE_KEYCHAIN "Store the token in the keychain (default)" ON) option(ENABLE_NOTIFICATION_SOUNDS "Enable notification sounds (default)" ON) +option(ENABLE_QRCODE_LOGIN "Enable QR code login (default)" ON) find_package(nlohmann_json REQUIRED) find_package(CURL) @@ -61,11 +62,14 @@ target_include_directories(abaddon PUBLIC ${ZLIB_INCLUDE_DIRS}) target_include_directories(abaddon PUBLIC ${SQLite3_INCLUDE_DIRS}) target_include_directories(abaddon PUBLIC ${NLOHMANN_JSON_INCLUDE_DIRS}) -add_library(qrcodegen subprojects/qrcodegen/cpp/qrcodegen.hpp subprojects/qrcodegen/cpp/qrcodegen.cpp) -target_include_directories(qrcodegen PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/subprojects/qrcodegen/cpp") -target_link_libraries(abaddon qrcodegen) +if (ENABLE_QRCODE_LOGIN) + add_library(qrcodegen subprojects/qrcodegen/cpp/qrcodegen.hpp subprojects/qrcodegen/cpp/qrcodegen.cpp) + target_include_directories(qrcodegen PUBLIC "${CMAKE_CURRENT_SOURCE_DIR}/subprojects/qrcodegen/cpp") + target_link_libraries(abaddon qrcodegen) -target_include_directories(abaddon PUBLIC "subprojects/qrcodegen/cpp") + target_include_directories(abaddon PUBLIC "subprojects/qrcodegen/cpp") + target_compile_definitions(abaddon PRIVATE WITH_QRLOGIN) +endif () target_precompile_headers(abaddon PRIVATE src/abaddon.hpp src/util.hpp) diff --git a/src/abaddon.cpp b/src/abaddon.cpp index c161595..921549b 100644 --- a/src/abaddon.cpp +++ b/src/abaddon.cpp @@ -837,6 +837,7 @@ void Abaddon::ActionSetToken() { } void Abaddon::ActionLoginQR() { +#ifdef WITH_QRLOGIN RemoteAuthDialog dlg(*m_main_window); auto response = dlg.run(); if (response == Gtk::RESPONSE_OK) { @@ -847,6 +848,7 @@ void Abaddon::ActionLoginQR() { ActionConnect(); } m_main_window->UpdateMenus(); +#endif } void Abaddon::ActionChannelOpened(Snowflake id, bool expand_to) { diff --git a/src/remoteauth/remoteauthclient.cpp b/src/remoteauth/remoteauthclient.cpp index 467ea8b..7653b78 100644 --- a/src/remoteauth/remoteauthclient.cpp +++ b/src/remoteauth/remoteauthclient.cpp @@ -1,8 +1,14 @@ +#ifdef WITH_QRLOGIN + +// clang-format off + #include "remoteauthclient.hpp" #include "http.hpp" #include #include +// clang-format on + RemoteAuthClient::RemoteAuthClient() : m_ws("remote-auth-ws") , m_log(spdlog::get("remote-auth")) { @@ -341,3 +347,5 @@ RemoteAuthClient::type_signal_token RemoteAuthClient::signal_token() { RemoteAuthClient::type_signal_error RemoteAuthClient::signal_error() { return m_signal_error; } + +#endif diff --git a/src/remoteauth/remoteauthclient.hpp b/src/remoteauth/remoteauthclient.hpp index c2e00f3..6ab6dbb 100644 --- a/src/remoteauth/remoteauthclient.hpp +++ b/src/remoteauth/remoteauthclient.hpp @@ -1,4 +1,9 @@ #pragma once + +#ifdef WITH_QRLOGIN + +// clang-format off + #include #include #include @@ -6,6 +11,8 @@ #include "discord/waiter.hpp" #include "discord/websocket.hpp" +// clang-format on + class RemoteAuthClient { public: RemoteAuthClient(); @@ -84,3 +91,5 @@ private: type_signal_token m_signal_token; type_signal_error m_signal_error; }; + +#endif diff --git a/src/remoteauth/remoteauthdialog.cpp b/src/remoteauth/remoteauthdialog.cpp index 7ee045f..7975b4e 100644 --- a/src/remoteauth/remoteauthdialog.cpp +++ b/src/remoteauth/remoteauthdialog.cpp @@ -1,6 +1,12 @@ +#ifdef WITH_QRLOGIN + +// clang-format off + #include "remoteauthdialog.hpp" #include +// clang-format on + RemoteAuthDialog::RemoteAuthDialog(Gtk::Window &parent) : Gtk::Dialog("Login with QR Code", parent, true) , m_layout(Gtk::ORIENTATION_VERTICAL) @@ -122,3 +128,5 @@ void RemoteAuthDialog::OnError(const std::string &error) { Abaddon::Get().ShowConfirm(error, dynamic_cast(get_toplevel())); response(Gtk::RESPONSE_CANCEL); } + +#endif diff --git a/src/remoteauth/remoteauthdialog.hpp b/src/remoteauth/remoteauthdialog.hpp index 9a6ca29..465a188 100644 --- a/src/remoteauth/remoteauthdialog.hpp +++ b/src/remoteauth/remoteauthdialog.hpp @@ -1,7 +1,14 @@ #pragma once + +#ifdef WITH_QRLOGIN + +// clang-format off + #include #include "remoteauthclient.hpp" +// clang-format on + class RemoteAuthDialog : public Gtk::Dialog { public: RemoteAuthDialog(Gtk::Window &parent); @@ -27,3 +34,5 @@ private: std::string m_token; }; + +#endif diff --git a/src/windows/mainwindow.cpp b/src/windows/mainwindow.cpp index 56d735e..0b21567 100644 --- a/src/windows/mainwindow.cpp +++ b/src/windows/mainwindow.cpp @@ -206,7 +206,9 @@ void MainWindow::OnDiscordSubmenuPopup() { m_menu_discord_connect.set_sensitive(!token.empty() && !discord_active); m_menu_discord_disconnect.set_sensitive(discord_active); m_menu_discord_set_token.set_sensitive(!discord_active); +#ifdef WITH_QRLOGIN m_menu_discord_login_qr.set_sensitive(!discord_active); +#endif m_menu_discord_set_status.set_sensitive(discord_active); } @@ -249,6 +251,10 @@ void MainWindow::SetupMenu() { m_menu_discord_disconnect.set_sensitive(false); m_menu_discord_set_token.set_label("Set Token"); m_menu_discord_login_qr.set_label("Login with QR Code"); +#ifndef WITH_QRLOGIN + m_menu_discord_login_qr.set_sensitive(false); + m_menu_discord_login_qr.set_tooltip_text("Not compiled with support"); +#endif m_menu_discord_set_status.set_label("Set Status"); m_menu_discord_set_status.set_sensitive(false); m_menu_discord_add_recipient.set_label("Add user to DM"); -- cgit v1.2.3