229 lines
5.2 KiB
C++
229 lines
5.2 KiB
C++
#include "authmanager.h"
|
|
#include "networkmanager.h"
|
|
#include <QDebug>
|
|
#include <QJsonDocument>
|
|
#include <QJsonObject>
|
|
#include <QNetworkReply>
|
|
#include <QSettings>
|
|
|
|
namespace
|
|
{
|
|
constexpr char key[] = "network/session_token";
|
|
}
|
|
|
|
AuthManager::AuthManager(QObject *parent)
|
|
: QObject{parent}, m_sessionData(nullptr), m_settings(new QSettings(this)), m_isSignedIn(false), m_lastEmail(""),
|
|
m_sessionToken("")
|
|
{
|
|
connect(&NetworkManager::instance(), &NetworkManager::unauthorizedDetected, this, [this]() {
|
|
if (!m_isSignedIn)
|
|
{
|
|
return;
|
|
}
|
|
|
|
setIsSignedIn(false);
|
|
if (m_sessionData)
|
|
{
|
|
delete m_sessionData;
|
|
m_sessionData = nullptr;
|
|
}
|
|
setSessionToken("");
|
|
});
|
|
}
|
|
|
|
void AuthManager::tryRestoreSession()
|
|
{
|
|
QString storageSessionToken = m_settings->value(key).toString();
|
|
if (storageSessionToken.isEmpty())
|
|
{
|
|
return;
|
|
}
|
|
qDebug() << "Storage session token is: " << storageSessionToken;
|
|
|
|
// set it here, and unset if it fails...network manager needs to inject into the request
|
|
setSessionToken(storageSessionToken);
|
|
|
|
QNetworkReply *reply = NetworkManager::instance().get("/auth/me");
|
|
connect(reply, &QNetworkReply::finished, this, [=]() {
|
|
reply->deleteLater();
|
|
|
|
if (reply->error() != QNetworkReply::NoError)
|
|
{
|
|
qDebug() << "Saved session token is invalid";
|
|
setSessionToken("");
|
|
return;
|
|
}
|
|
|
|
qDebug() << "Saved session token is valid";
|
|
|
|
QByteArray responseData = reply->readAll();
|
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
|
|
if (jsonDoc.isNull())
|
|
{
|
|
qWarning() << "Failed to create a JSON doc.";
|
|
setSessionToken("");
|
|
return;
|
|
}
|
|
|
|
QJsonObject jsonObj = jsonDoc.object();
|
|
|
|
if (!m_sessionData)
|
|
{
|
|
m_sessionData = new SessionData{};
|
|
}
|
|
m_sessionData->id = jsonObj["id"].toString();
|
|
m_sessionData->email = jsonObj["email"].toString();
|
|
m_sessionData->emailPrefix = jsonObj["email_prefix"].toString();
|
|
|
|
setSessionToken(storageSessionToken);
|
|
|
|
setIsSignedIn(true);
|
|
});
|
|
}
|
|
|
|
void AuthManager::setIsSignedIn(bool newValue)
|
|
{
|
|
if (m_isSignedIn == newValue)
|
|
{
|
|
return;
|
|
}
|
|
|
|
m_isSignedIn = newValue;
|
|
emit isSignedInChanged();
|
|
|
|
if (m_isSignedIn)
|
|
{
|
|
emit signedIn();
|
|
}
|
|
else
|
|
{
|
|
emit signedOut();
|
|
}
|
|
}
|
|
|
|
bool AuthManager::isSignedIn() const
|
|
{
|
|
return m_isSignedIn;
|
|
}
|
|
|
|
SessionData *AuthManager::sessionData() const
|
|
{
|
|
return m_sessionData;
|
|
}
|
|
|
|
void AuthManager::requestSignInCode(const QString &email)
|
|
{
|
|
if (isSignedIn())
|
|
{
|
|
qWarning() << "Must sign out first";
|
|
return;
|
|
}
|
|
|
|
QJsonDocument body;
|
|
QJsonObject object;
|
|
object["email"] = email;
|
|
body.setObject(object);
|
|
QNetworkReply *reply = NetworkManager::instance().post("/auth/request-code", body);
|
|
|
|
connect(reply, &QNetworkReply::finished, this, [=]() {
|
|
reply->deleteLater();
|
|
if (reply->error() != QNetworkReply::NoError)
|
|
{
|
|
emit errorOccurred("Unable to send code. Please try again.");
|
|
qDebug() << "Error in emailing auth code: " << reply->errorString();
|
|
return;
|
|
}
|
|
|
|
qDebug() << "Code successfully sent";
|
|
m_lastEmail = email;
|
|
emit codeSentToEmail(email);
|
|
});
|
|
}
|
|
|
|
void AuthManager::signIn(const QString &code)
|
|
{
|
|
if (isSignedIn())
|
|
{
|
|
qWarning() << "Must sign out first";
|
|
return;
|
|
}
|
|
assert(!m_lastEmail.isEmpty());
|
|
|
|
QJsonDocument body;
|
|
QJsonObject object;
|
|
object["email"] = m_lastEmail;
|
|
object["code"] = code;
|
|
body.setObject(object);
|
|
QNetworkReply *reply = NetworkManager::instance().post("/auth/sign-in", body);
|
|
|
|
connect(reply, &QNetworkReply::finished, this, [=]() {
|
|
reply->deleteLater();
|
|
if (reply->error() != QNetworkReply::NoError)
|
|
{
|
|
emit errorOccurred("Unable to verify code. Please try again.");
|
|
qDebug() << "Error in verify code: " << reply->errorString();
|
|
return;
|
|
}
|
|
|
|
qDebug() << "Session successfully created";
|
|
QByteArray responseData = reply->readAll();
|
|
QJsonDocument jsonDoc = QJsonDocument::fromJson(responseData);
|
|
if (jsonDoc.isNull())
|
|
{
|
|
qWarning() << "Failed to create a JSON doc.";
|
|
emit errorOccurred("Unable to verify code");
|
|
return;
|
|
}
|
|
|
|
QJsonObject jsonObj = jsonDoc.object();
|
|
|
|
if (!m_sessionData)
|
|
{
|
|
m_sessionData = new SessionData{};
|
|
}
|
|
QJsonObject human = jsonObj["human"].toObject();
|
|
m_sessionData->id = human["id"].toString();
|
|
m_sessionData->email = human["email"].toString();
|
|
m_sessionData->emailPrefix = human["email_prefix"].toString();
|
|
|
|
setSessionToken(jsonObj["token"].toString());
|
|
|
|
setIsSignedIn(true);
|
|
});
|
|
}
|
|
|
|
void AuthManager::signOut()
|
|
{
|
|
if (!isSignedIn())
|
|
{
|
|
qWarning() << "Not signed in, skipping sign out";
|
|
return;
|
|
}
|
|
|
|
setIsSignedIn(false);
|
|
if (m_sessionData)
|
|
{
|
|
delete m_sessionData;
|
|
m_sessionData = nullptr;
|
|
}
|
|
setSessionToken("");
|
|
|
|
QNetworkReply *reply = NetworkManager::instance().post("/auth/sign-out", QJsonDocument());
|
|
connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater);
|
|
}
|
|
|
|
void AuthManager::setSessionToken(const QString &newValue)
|
|
{
|
|
if (newValue.isEmpty())
|
|
{
|
|
m_settings->remove(key);
|
|
}
|
|
else
|
|
{
|
|
m_settings->setValue(key, newValue);
|
|
}
|
|
|
|
m_sessionToken = newValue;
|
|
NetworkManager::instance().setSessionToken(newValue);
|
|
}
|