File indexing completed on 2024-05-12 16:27:23

0001 /*
0002    SPDX-FileCopyrightText: 2021-2024 Laurent Montel <montel@kde.org>
0003 
0004    SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 #include "myaccount2fatotpwidget.h"
0008 #include "ddpapi/ddpclient.h"
0009 #include "misc/lineeditcatchreturnkey.h"
0010 #include "rocketchataccount.h"
0011 #include <KLocalizedString>
0012 #include <KMessageBox>
0013 #include <QGuiApplication>
0014 #include <QLabel>
0015 #include <QLineEdit>
0016 #include <QPushButton>
0017 #include <QScreen>
0018 #include <QVBoxLayout>
0019 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0020 #include <prison/Prison>
0021 #else
0022 #include <Prison/Prison>
0023 #endif
0024 
0025 MyAccount2FaTotpWidget::MyAccount2FaTotpWidget(RocketChatAccount *account, QWidget *parent)
0026     : QWidget{parent}
0027 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0028     , mQRCode(Prison::createBarcode(Prison::QRCode))
0029 #else
0030     , mQRCode(Prison::Barcode::create(Prison::QRCode))
0031 #endif
0032     , mTotpQrCode(new QLabel(this))
0033     , mQrCoreLabel(new QLabel(this))
0034     , mVerifyQrCode(new QLineEdit(this))
0035     , mRocketChatAccount(account)
0036 {
0037     auto mainLayout = new QVBoxLayout(this);
0038     mainLayout->setObjectName(QStringLiteral("mainLayout"));
0039     mainLayout->setContentsMargins({});
0040 
0041     mTotpQrCode->setObjectName(QStringLiteral("mTotpQrCode"));
0042     mainLayout->addWidget(mTotpQrCode);
0043     auto label = new QLabel(i18n("Scan the QR code. It will display a 6 digit code which you need to enter below."
0044                                  "\n If you can't scan the QR code, you may enter code manually instead:"),
0045                             this);
0046     label->setObjectName(QStringLiteral("label"));
0047     mainLayout->addWidget(label);
0048 
0049     mQrCoreLabel->setObjectName(QStringLiteral("mQrCoreLabel"));
0050     mainLayout->addWidget(mQrCoreLabel);
0051     mQrCoreLabel->setTextFormat(Qt::PlainText);
0052     mQrCoreLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
0053 
0054     auto hboxLayout = new QHBoxLayout;
0055     hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
0056     hboxLayout->setContentsMargins({});
0057     mainLayout->addLayout(hboxLayout);
0058 
0059     mVerifyQrCode->setObjectName(QStringLiteral("mVerifyQrCode"));
0060     mVerifyQrCode->setPlaceholderText(i18n("Enter authentication code"));
0061     new LineEditCatchReturnKey(mVerifyQrCode, this);
0062     hboxLayout->addWidget(mVerifyQrCode);
0063 
0064     auto verifyButton = new QPushButton(i18n("Verify"), this);
0065     verifyButton->setObjectName(QStringLiteral("verifyButton"));
0066     hboxLayout->addWidget(verifyButton);
0067     verifyButton->setEnabled(false);
0068     connect(verifyButton, &QPushButton::clicked, this, &MyAccount2FaTotpWidget::slotVerify);
0069     connect(mVerifyQrCode, &QLineEdit::textChanged, this, [verifyButton](const QString &str) {
0070         verifyButton->setEnabled(!str.trimmed().isEmpty());
0071     });
0072     connect(mVerifyQrCode, &QLineEdit::returnPressed, this, &MyAccount2FaTotpWidget::slotVerify);
0073     if (mRocketChatAccount) {
0074         connect(mRocketChatAccount, &RocketChatAccount::totpResult, this, &MyAccount2FaTotpWidget::slotTotpResult);
0075         connect(mRocketChatAccount, &RocketChatAccount::totpInvalid, this, &MyAccount2FaTotpWidget::slotTotpInvalid);
0076         connect(mRocketChatAccount, &RocketChatAccount::totpValid, this, &MyAccount2FaTotpWidget::slotTotpValid);
0077     }
0078     mainLayout->addStretch(1);
0079 }
0080 
0081 MyAccount2FaTotpWidget::~MyAccount2FaTotpWidget()
0082 {
0083 #if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
0084     delete mQRCode;
0085 #endif
0086 }
0087 
0088 void MyAccount2FaTotpWidget::slotTotpValid(const QStringList &listCodes)
0089 {
0090     KMessageBox::information(
0091         this,
0092         i18n("Make sure you have a copy of your codes:\n%1\nIf you lose access to your authenticator app, you can use one of these codes to log in.",
0093              listCodes.join(QLatin1Char('\n'))),
0094         i18n("Backup Codes"));
0095     setVisible(false); // Hide it.
0096 }
0097 
0098 void MyAccount2FaTotpWidget::slotTotpInvalid()
0099 {
0100     KMessageBox::error(this, i18n("Invalid two factor code."), i18n("Check Two Factor Code"));
0101 }
0102 
0103 void MyAccount2FaTotpWidget::slotVerify()
0104 {
0105     mRocketChatAccount->ddp()->validateTempToken2fa(mVerifyQrCode->text());
0106 }
0107 
0108 void MyAccount2FaTotpWidget::slotTotpResult(const QString &secret, const QString &url)
0109 {
0110     mQrCoreLabel->setText(secret);
0111     mQRCode->setData(url);
0112     mTotpQrCode->setPixmap(QPixmap::fromImage(mQRCode->toImage(mQRCode->preferredSize(QGuiApplication::primaryScreen()->devicePixelRatio()).toSize())));
0113     Q_EMIT show2FaEnabledWidget();
0114 }
0115 
0116 #include "moc_myaccount2fatotpwidget.cpp"