File indexing completed on 2024-12-01 04:36:52

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 "rocketchataccount.h"
0010 #include <KLineEditEventHandler>
0011 #include <KLocalizedString>
0012 #include <KMessageBox>
0013 #include <Prison/Prison>
0014 #include <QGuiApplication>
0015 #include <QLabel>
0016 #include <QLineEdit>
0017 #include <QPushButton>
0018 #include <QScreen>
0019 #include <QVBoxLayout>
0020 
0021 MyAccount2FaTotpWidget::MyAccount2FaTotpWidget(RocketChatAccount *account, QWidget *parent)
0022     : QWidget{parent}
0023     , mQRCode(Prison::Barcode::create(Prison::QRCode))
0024     , mTotpQrCode(new QLabel(this))
0025     , mQrCoreLabel(new QLabel(this))
0026     , mVerifyQrCode(new QLineEdit(this))
0027     , mRocketChatAccount(account)
0028 {
0029     auto mainLayout = new QVBoxLayout(this);
0030     mainLayout->setObjectName(QStringLiteral("mainLayout"));
0031     mainLayout->setContentsMargins({});
0032 
0033     mTotpQrCode->setObjectName(QStringLiteral("mTotpQrCode"));
0034     mainLayout->addWidget(mTotpQrCode);
0035     auto label = new QLabel(i18n("Scan the QR code. It will display a 6 digit code which you need to enter below."
0036                                  "\n If you can't scan the QR code, you may enter code manually instead:"),
0037                             this);
0038     label->setObjectName(QStringLiteral("label"));
0039     mainLayout->addWidget(label);
0040 
0041     mQrCoreLabel->setObjectName(QStringLiteral("mQrCoreLabel"));
0042     mainLayout->addWidget(mQrCoreLabel);
0043     mQrCoreLabel->setTextFormat(Qt::PlainText);
0044     mQrCoreLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
0045 
0046     auto hboxLayout = new QHBoxLayout;
0047     hboxLayout->setObjectName(QStringLiteral("hboxLayout"));
0048     hboxLayout->setContentsMargins({});
0049     mainLayout->addLayout(hboxLayout);
0050 
0051     mVerifyQrCode->setObjectName(QStringLiteral("mVerifyQrCode"));
0052     mVerifyQrCode->setPlaceholderText(i18n("Enter authentication code"));
0053     KLineEditEventHandler::catchReturnKey(mVerifyQrCode);
0054     hboxLayout->addWidget(mVerifyQrCode);
0055 
0056     auto verifyButton = new QPushButton(i18n("Verify"), this);
0057     verifyButton->setObjectName(QStringLiteral("verifyButton"));
0058     hboxLayout->addWidget(verifyButton);
0059     verifyButton->setEnabled(false);
0060     connect(verifyButton, &QPushButton::clicked, this, &MyAccount2FaTotpWidget::slotVerify);
0061     connect(mVerifyQrCode, &QLineEdit::textChanged, this, [verifyButton](const QString &str) {
0062         verifyButton->setEnabled(!str.trimmed().isEmpty());
0063     });
0064     connect(mVerifyQrCode, &QLineEdit::returnPressed, this, &MyAccount2FaTotpWidget::slotVerify);
0065     if (mRocketChatAccount) {
0066         connect(mRocketChatAccount, &RocketChatAccount::totpResult, this, &MyAccount2FaTotpWidget::slotTotpResult);
0067         connect(mRocketChatAccount, &RocketChatAccount::totpInvalid, this, &MyAccount2FaTotpWidget::slotTotpInvalid);
0068         connect(mRocketChatAccount, &RocketChatAccount::totpValid, this, &MyAccount2FaTotpWidget::slotTotpValid);
0069     }
0070     mainLayout->addStretch(1);
0071 }
0072 
0073 MyAccount2FaTotpWidget::~MyAccount2FaTotpWidget() = default;
0074 
0075 void MyAccount2FaTotpWidget::slotTotpValid(const QStringList &listCodes)
0076 {
0077     KMessageBox::information(
0078         this,
0079         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.",
0080              listCodes.join(QLatin1Char('\n'))),
0081         i18n("Backup Codes"));
0082     setVisible(false); // Hide it.
0083 }
0084 
0085 void MyAccount2FaTotpWidget::slotTotpInvalid()
0086 {
0087     KMessageBox::error(this, i18n("Invalid two factor code."), i18n("Check Two Factor Code"));
0088 }
0089 
0090 void MyAccount2FaTotpWidget::slotVerify()
0091 {
0092     mRocketChatAccount->ddp()->validateTempToken2fa(mVerifyQrCode->text());
0093 }
0094 
0095 void MyAccount2FaTotpWidget::slotTotpResult(const QString &secret, const QString &url)
0096 {
0097     mQrCoreLabel->setText(secret);
0098     mQRCode->setData(url);
0099     mTotpQrCode->setPixmap(QPixmap::fromImage(mQRCode->toImage(mQRCode->preferredSize(QGuiApplication::primaryScreen()->devicePixelRatio()).toSize())));
0100     Q_EMIT show2FaEnabledWidget();
0101 }
0102 
0103 #include "moc_myaccount2fatotpwidget.cpp"