Skip to content

Commit

Permalink
Merge pull request #185 from uowuo/remoteauth
Browse files Browse the repository at this point in the history
Login with QR code/remote auth
  • Loading branch information
ouwou authored Jul 13, 2023
2 parents 9a3f6b4 + 5bf5cc7 commit 337a3d5
Show file tree
Hide file tree
Showing 17 changed files with 736 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ jobs:
with:
cond: ${{ matrix.mindeps == true }}
if_true: |
cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=${{ matrix.buildtype }} -DUSE_LIBHANDY=OFF -DENABLE_VOICE=OFF -DENABLE_NOTIFICATION_SOUNDS=OFF
cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=${{ matrix.buildtype }} -DUSE_LIBHANDY=OFF -DENABLE_VOICE=OFF -DENABLE_NOTIFICATION_SOUNDS=OFF -DENABLE_QRCODE_LOGIN=OFF
cmake --build build
if_false: |
cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=${{ matrix.buildtype }} -DCMAKE_CXX_FLAGS="-Wl,--default-image-base-low"
Expand Down
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@
[submodule "subprojects/miniaudio"]
path = subprojects/miniaudio
url = https://github.com/mackron/miniaudio
[submodule "subprojects/qrcodegen"]
path = subprojects/qrcodegen
url = https://github.com/nayuki/QR-Code-generator
22 changes: 16 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -61,6 +62,15 @@ 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})

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_compile_definitions(abaddon PRIVATE WITH_QRLOGIN)
endif ()

target_precompile_headers(abaddon PRIVATE <gtkmm.h> src/abaddon.hpp src/util.hpp)

if ((CMAKE_CXX_COMPILER_ID STREQUAL "GNU") OR
Expand Down Expand Up @@ -151,12 +161,12 @@ if (ENABLE_VOICE)

target_link_libraries(abaddon ${CMAKE_DL_LIBS})

if(APPLE)
target_link_libraries(abaddon "-framework CoreFoundation")
target_link_libraries(abaddon "-framework CoreAudio")
target_link_libraries(abaddon "-framework AudioToolbox")
endif()
if (APPLE)
target_link_libraries(abaddon "-framework CoreFoundation")
target_link_libraries(abaddon "-framework CoreAudio")
target_link_libraries(abaddon "-framework AudioToolbox")
endif ()

endif ()

if (${ENABLE_NOTIFICATION_SOUNDS})
Expand Down
18 changes: 18 additions & 0 deletions src/abaddon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include "windows/voicewindow.hpp"
#include "startup.hpp"
#include "notifications/notifications.hpp"
#include "remoteauth/remoteauthdialog.hpp"

#ifdef WITH_LIBHANDY
#include <handy.h>
Expand Down Expand Up @@ -267,6 +268,7 @@ int Abaddon::StartGTK() {
m_main_window->signal_action_connect().connect(sigc::mem_fun(*this, &Abaddon::ActionConnect));
m_main_window->signal_action_disconnect().connect(sigc::mem_fun(*this, &Abaddon::ActionDisconnect));
m_main_window->signal_action_set_token().connect(sigc::mem_fun(*this, &Abaddon::ActionSetToken));
m_main_window->signal_action_login_qr().connect(sigc::mem_fun(*this, &Abaddon::ActionLoginQR));
m_main_window->signal_action_reload_css().connect(sigc::mem_fun(*this, &Abaddon::ActionReloadCSS));
m_main_window->signal_action_set_status().connect(sigc::mem_fun(*this, &Abaddon::ActionSetStatus));
m_main_window->signal_action_add_recipient().connect(sigc::mem_fun(*this, &Abaddon::ActionAddRecipient));
Expand Down Expand Up @@ -834,6 +836,21 @@ void Abaddon::ActionSetToken() {
m_main_window->UpdateMenus();
}

void Abaddon::ActionLoginQR() {
#ifdef WITH_QRLOGIN
RemoteAuthDialog dlg(*m_main_window);
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;
ActionConnect();
}
m_main_window->UpdateMenus();
#endif
}

void Abaddon::ActionChannelOpened(Snowflake id, bool expand_to) {
if (!id.IsValid()) {
m_discord.SetReferringChannel(Snowflake::Invalid);
Expand Down Expand Up @@ -1142,6 +1159,7 @@ int main(int argc, char **argv) {
auto log_audio = spdlog::stdout_color_mt("audio");
auto log_voice = spdlog::stdout_color_mt("voice");
auto log_discord = spdlog::stdout_color_mt("discord");
auto log_ra = spdlog::stdout_color_mt("remote-auth");

Gtk::Main::init_gtkmm_internals(); // why???
return Abaddon::Get().StartGTK();
Expand Down
1 change: 1 addition & 0 deletions src/abaddon.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ class Abaddon {
void ActionConnect();
void ActionDisconnect();
void ActionSetToken();
void ActionLoginQR();
void ActionJoinGuildDialog();
void ActionChannelOpened(Snowflake id, bool expand_to = true);
void ActionChatInputSubmit(ChatSubmitParams data);
Expand Down
21 changes: 21 additions & 0 deletions src/discord/discord.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,27 @@ void DiscordClient::AcceptVerificationGate(Snowflake guild_id, VerificationGateI
});
}

void DiscordClient::RemoteAuthLogin(const std::string &ticket, const sigc::slot<void(std::optional<std::string>, 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<std::string>(), 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));
}
});
}

#ifdef WITH_VOICE
void DiscordClient::ConnectToVoice(Snowflake channel_id) {
auto channel = GetChannel(channel_id);
Expand Down
2 changes: 2 additions & 0 deletions src/discord/discord.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,8 @@ class DiscordClient {
void GetVerificationGateInfo(Snowflake guild_id, const sigc::slot<void(std::optional<VerificationGateInfoObject>)> &callback);
void AcceptVerificationGate(Snowflake guild_id, VerificationGateInfoObject info, const sigc::slot<void(DiscordError code)> &callback);

void RemoteAuthLogin(const std::string &ticket, const sigc::slot<void(std::optional<std::string>, DiscordError code)> &callback);

#ifdef WITH_VOICE
void ConnectToVoice(Snowflake channel_id);
void DisconnectFromVoice();
Expand Down
1 change: 1 addition & 0 deletions src/discord/errors.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ enum class DiscordError {
RELATIONSHIP_ALREADY_FRIENDS = 80007,

NONE = -1,
CAPTCHA_REQUIRED = -2,
};

constexpr const char *GetDiscordErrorDisplayString(DiscordError error) {
Expand Down
5 changes: 4 additions & 1 deletion src/discord/websocket.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ void Websocket::StartConnection(const std::string &url) {
m_websocket->disableAutomaticReconnection();
m_websocket->setUrl(url);
m_websocket->setOnMessageCallback([this](auto &&msg) { OnMessage(std::forward<decltype(msg)>(msg)); });
m_websocket->setExtraHeaders(ix::WebSocketHttpHeaders { { "User-Agent", m_agent } }); // idk if this actually works
m_websocket->setExtraHeaders(ix::WebSocketHttpHeaders { { "User-Agent", m_agent }, { "Origin", "https://discord.com" } }); // idk if this actually works
m_websocket->start();
}

Expand Down Expand Up @@ -81,6 +81,9 @@ void Websocket::OnMessage(const ix::WebSocketMessagePtr &msg) {
case ix::WebSocketMessageType::Message: {
m_signal_message.emit(msg->str);
} break;
case ix::WebSocketMessageType::Error: {
m_log->error("Websocket error: Status: {} Reason: {}", msg->errorInfo.http_status, msg->errorInfo.reason);
} break;
default:
break;
}
Expand Down
Loading

0 comments on commit 337a3d5

Please sign in to comment.