#include "mainwindow.h" #include #include #include #include #include #include #include #include #include #include #include void MainWindow::handleOutput() { QString content = m_box->text(); m_box->setText(""); switch(state) { case Unauthed: { if(!content.startsWith("/login ")) { addMessage("You are currently unauthenticated, you can't send messages or use commands!", Error); return; } m_box->setEchoMode(QLineEdit::NoEcho); m_box->setPlaceholderText("Enter your password"); state = PendingPassword; m_pendingAuthObject.setEmail(content.replace("/login ", "")); addMessage(QString("Logging in as %1. Enter your password then press Enter. (you won't be able to see any characters)").arg(content.replace("/login ", "")), System); addMessage("If you'd like to cancel at any time, type 'cancel'.", System); break; } case PendingPassword: { m_box->setEchoMode(QLineEdit::Normal); m_box->setPlaceholderText("Message (or /command)"); state = Unauthed; if(content == "cancel") { addMessage("Cancelled.", System); break; } addMessage("Logging in, please be patient...", System); QNetworkRequest request = DiscordRequests::buildRequest("auth/login", false, true); QJsonObject data; data["undelete"] = true; data["email"] = m_pendingAuthObject.getEmail(); data["password"] = content; m_netmgr->post(request, QJsonDocument(data).toJson()); break; } case PendingOTP: { if(content == "cancel") { addMessage("Cancelled.", System); break; } static QRegularExpression re("\\d*"); if(!re.match(content).hasMatch() || content.length() > 8 || content.length() < 6 || content.length() == 7) { addMessage("A valid TOTP or backup code is required. Else, enter 'sms' to use SMS auth.", Error); break; } if(content.length() == 6) { QNetworkRequest request = DiscordRequests::buildRequest("auth/mfa/totp", false, true); QJsonObject data; data["ticket"] = m_pendingAuthObject.get2faToken(); data["code"] = content; m_netmgr->post(request, QJsonDocument(data).toJson()); } if(content.length() == 8) { QNetworkRequest request = DiscordRequests::buildRequest("auth/mfa/backup", false, true); QJsonObject data; data["ticket"] = m_pendingAuthObject.get2faToken(); data["code"] = content; m_netmgr->post(request, QJsonDocument(data).toJson()); } break; } } } void MainWindow::addMessage(QString content, MainWindow::MessageType type) { if(type == Normal) { m_chatlog->append(content); } if(type == System) { m_chatlog->append(QString("[Sys] %1

").arg(content)); } if(type == Error) { m_chatlog->append(QString("Error: %1

").arg(content)); } } void MainWindow::handleHttpReply(QNetworkReply* reply) { QJsonDocument data = QJsonDocument::fromJson(reply->readAll()); if(reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) != 200) { addMessage("Something happened", Error); return; } // == AUTH == // if(data["mfa"].toBool() && reply->attribute(QNetworkRequest::HttpStatusCodeAttribute) == 200) { m_pendingAuthObject.set2faToken(data["ticket"].toString()); m_box->setPlaceholderText("Enter your code (or sms)"); state = PendingOTP; if(data["sms"].toBool()) { addMessage("2FA is required to login to this account. Available options: authenticator app, backup codes, SMS auth", System); addMessage("To use TOTP/backup auth, simply enter your 6-8 digit code. For SMS auth, type 'sms'.", System); } else { addMessage("2FA is required to login to this account. Available options: authenticator app, backup codes", System); addMessage("Enter your 6-8 digit code.", System); } } if(data["token"].toString() != "") { QSettings settings; settings.setValue("token", data["token"].toString()); addMessage("Auth done!", System); } // == END AUTH == // } MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) { QCoreApplication::setOrganizationName("nin0dev"); QCoreApplication::setApplicationName("txtcord"); QSettings settings; QWidget *centralWidget = new QWidget(this); m_layout = new QVBoxLayout(centralWidget); setCentralWidget(centralWidget); // init network manager m_pendingAuthObject = PendingAuthObject(); m_netmgr = new QNetworkAccessManager(this); connect(m_netmgr, SIGNAL(finished(QNetworkReply*)), this, SLOT(handleHttpReply(QNetworkReply*))); // init chatlog m_chatlog = new QTextEdit(); m_chatlog->setReadOnly(true); m_chatlog->append("Welcome to txtcord, the minimal Discord client."); if(settings.value("token").isNull()) { addMessage("No accounts are saved. Use the /login [email/phone] command to sign in to your Discord account.", System); } else { addMessage("You are logged in, connecting to the Gateway... (soon)", System); state = NonConnected; } m_layout->addWidget(m_chatlog); // init chatbox QWidget *chatboxWidget = new QWidget(); QHBoxLayout *chatboxLayout = new QHBoxLayout(); m_box = new QLineEdit(); m_box->setPlaceholderText("Message (or /command)"); chatboxLayout->addWidget(m_box); m_send = new QPushButton(); m_send->setText("Send"); chatboxLayout->addWidget(m_send); chatboxWidget->setLayout(chatboxLayout); m_layout->addWidget(chatboxWidget); connect(m_box, SIGNAL(returnPressed()), this, SLOT(handleOutput())); } MainWindow::~MainWindow() { }