mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-11-28 10:31:13 -05:00
Add TOTP support
This commit is contained in:
parent
7040bef27e
commit
bf57a28654
22 changed files with 1120 additions and 2 deletions
|
|
@ -42,6 +42,8 @@
|
|||
#include "gui/ChangeMasterKeyWidget.h"
|
||||
#include "gui/Clipboard.h"
|
||||
#include "gui/CloneDialog.h"
|
||||
#include "gui/SetupTotpDialog.h"
|
||||
#include "gui/TotpDialog.h"
|
||||
#include "gui/DatabaseOpenWidget.h"
|
||||
#include "gui/DatabaseSettingsWidget.h"
|
||||
#include "gui/KeePass1OpenWidget.h"
|
||||
|
|
@ -333,6 +335,48 @@ void DatabaseWidget::cloneEntry()
|
|||
return;
|
||||
}
|
||||
|
||||
void DatabaseWidget::showTotp()
|
||||
{
|
||||
Entry* currentEntry = m_entryView->currentEntry();
|
||||
if (!currentEntry) {
|
||||
Q_ASSERT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
TotpDialog* totpDialog = new TotpDialog(this, currentEntry);
|
||||
totpDialog->open();
|
||||
}
|
||||
|
||||
void DatabaseWidget::copyTotp()
|
||||
{
|
||||
Entry* currentEntry = m_entryView->currentEntry();
|
||||
if (!currentEntry) {
|
||||
Q_ASSERT(false);
|
||||
return;
|
||||
}
|
||||
setClipboardTextAndMinimize(currentEntry->totp());
|
||||
}
|
||||
|
||||
void DatabaseWidget::setupTotp()
|
||||
{
|
||||
Entry* currentEntry = m_entryView->currentEntry();
|
||||
if (!currentEntry) {
|
||||
Q_ASSERT(false);
|
||||
return;
|
||||
}
|
||||
|
||||
SetupTotpDialog* setupTotpDialog = new SetupTotpDialog(this, currentEntry);
|
||||
if (currentEntry->hasTotp()) {
|
||||
setupTotpDialog->setSeed(currentEntry->totpSeed());
|
||||
setupTotpDialog->setStep(currentEntry->totpStep());
|
||||
setupTotpDialog->setDigits(currentEntry->totpDigits());
|
||||
}
|
||||
|
||||
setupTotpDialog->open();
|
||||
|
||||
}
|
||||
|
||||
|
||||
void DatabaseWidget::deleteEntries()
|
||||
{
|
||||
const QModelIndexList selected = m_entryView->selectionModel()->selectedRows();
|
||||
|
|
@ -1225,6 +1269,17 @@ bool DatabaseWidget::currentEntryHasUrl()
|
|||
return !currentEntry->resolveMultiplePlaceholders(currentEntry->url()).isEmpty();
|
||||
}
|
||||
|
||||
|
||||
bool DatabaseWidget::currentEntryHasTotp()
|
||||
{
|
||||
Entry* currentEntry = m_entryView->currentEntry();
|
||||
if (!currentEntry) {
|
||||
Q_ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
return currentEntry->hasTotp();
|
||||
}
|
||||
|
||||
bool DatabaseWidget::currentEntryHasNotes()
|
||||
{
|
||||
Entry* currentEntry = m_entryView->currentEntry();
|
||||
|
|
|
|||
|
|
@ -96,6 +96,7 @@ public:
|
|||
bool currentEntryHasPassword();
|
||||
bool currentEntryHasUrl();
|
||||
bool currentEntryHasNotes();
|
||||
bool currentEntryHasTotp();
|
||||
GroupView* groupView();
|
||||
EntryView* entryView();
|
||||
void showUnlockDialog();
|
||||
|
|
@ -133,6 +134,9 @@ public slots:
|
|||
void copyURL();
|
||||
void copyNotes();
|
||||
void copyAttribute(QAction* action);
|
||||
void showTotp();
|
||||
void copyTotp();
|
||||
void setupTotp();
|
||||
void performAutoType();
|
||||
void openUrl();
|
||||
void openUrlForEntry(Entry* entry);
|
||||
|
|
|
|||
|
|
@ -167,6 +167,8 @@ MainWindow::MainWindow()
|
|||
m_ui->actionEntryEdit->setShortcut(Qt::CTRL + Qt::Key_E);
|
||||
m_ui->actionEntryDelete->setShortcut(Qt::CTRL + Qt::Key_D);
|
||||
m_ui->actionEntryClone->setShortcut(Qt::CTRL + Qt::Key_K);
|
||||
m_ui->actionEntryTotp->setShortcut(Qt::CTRL + Qt::SHIFT + Qt::Key_T);
|
||||
m_ui->actionEntryCopyTotp->setShortcut(Qt::CTRL + Qt::Key_T);
|
||||
m_ui->actionEntryCopyUsername->setShortcut(Qt::CTRL + Qt::Key_B);
|
||||
m_ui->actionEntryCopyPassword->setShortcut(Qt::CTRL + Qt::Key_C);
|
||||
setShortcut(m_ui->actionEntryAutoType, QKeySequence::Paste, Qt::CTRL + Qt::Key_V);
|
||||
|
|
@ -275,6 +277,13 @@ MainWindow::MainWindow()
|
|||
m_actionMultiplexer.connect(m_ui->actionEntryDelete, SIGNAL(triggered()),
|
||||
SLOT(deleteEntries()));
|
||||
|
||||
m_actionMultiplexer.connect(m_ui->actionEntryTotp, SIGNAL(triggered()),
|
||||
SLOT(showTotp()));
|
||||
m_actionMultiplexer.connect(m_ui->actionEntrySetupTotp, SIGNAL(triggered()),
|
||||
SLOT(setupTotp()));
|
||||
|
||||
m_actionMultiplexer.connect(m_ui->actionEntryCopyTotp, SIGNAL(triggered()),
|
||||
SLOT(copyTotp()));
|
||||
m_actionMultiplexer.connect(m_ui->actionEntryCopyTitle, SIGNAL(triggered()),
|
||||
SLOT(copyTitle()));
|
||||
m_actionMultiplexer.connect(m_ui->actionEntryCopyUsername, SIGNAL(triggered()),
|
||||
|
|
@ -428,8 +437,12 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|
|||
m_ui->actionEntryCopyURL->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUrl());
|
||||
m_ui->actionEntryCopyNotes->setEnabled(singleEntrySelected && dbWidget->currentEntryHasNotes());
|
||||
m_ui->menuEntryCopyAttribute->setEnabled(singleEntrySelected);
|
||||
m_ui->menuEntryTotp->setEnabled(true);
|
||||
m_ui->actionEntryAutoType->setEnabled(singleEntrySelected);
|
||||
m_ui->actionEntryOpenUrl->setEnabled(singleEntrySelected && dbWidget->currentEntryHasUrl());
|
||||
m_ui->actionEntryTotp->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp());
|
||||
m_ui->actionEntryCopyTotp->setEnabled(singleEntrySelected && dbWidget->currentEntryHasTotp());
|
||||
m_ui->actionEntrySetupTotp->setEnabled(singleEntrySelected);
|
||||
m_ui->actionGroupNew->setEnabled(groupSelected);
|
||||
m_ui->actionGroupEdit->setEnabled(groupSelected);
|
||||
m_ui->actionGroupDelete->setEnabled(groupSelected && dbWidget->canDeleteCurrentGroup());
|
||||
|
|
@ -463,6 +476,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|
|||
m_ui->actionEntryCopyURL->setEnabled(false);
|
||||
m_ui->actionEntryCopyNotes->setEnabled(false);
|
||||
m_ui->menuEntryCopyAttribute->setEnabled(false);
|
||||
m_ui->menuEntryTotp->setEnabled(false);
|
||||
|
||||
m_ui->actionChangeMasterKey->setEnabled(false);
|
||||
m_ui->actionChangeDatabaseSettings->setEnabled(false);
|
||||
|
|
@ -495,6 +509,7 @@ void MainWindow::setMenuActionState(DatabaseWidget::Mode mode)
|
|||
m_ui->actionEntryCopyURL->setEnabled(false);
|
||||
m_ui->actionEntryCopyNotes->setEnabled(false);
|
||||
m_ui->menuEntryCopyAttribute->setEnabled(false);
|
||||
m_ui->menuEntryTotp->setEnabled(false);
|
||||
|
||||
m_ui->actionChangeMasterKey->setEnabled(false);
|
||||
m_ui->actionChangeDatabaseSettings->setEnabled(false);
|
||||
|
|
|
|||
|
|
@ -220,9 +220,21 @@
|
|||
<addaction name="actionEntryCopyNotes"/>
|
||||
<addaction name="separator"/>
|
||||
</widget>
|
||||
<widget class="QMenu" name="menuEntryTotp">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>Timed one-time password</string>
|
||||
</property>
|
||||
<addaction name="actionEntryCopyTotp"/>
|
||||
<addaction name="actionEntryTotp"/>
|
||||
<addaction name="actionEntrySetupTotp"/>
|
||||
</widget>
|
||||
<addaction name="actionEntryCopyUsername"/>
|
||||
<addaction name="actionEntryCopyPassword"/>
|
||||
<addaction name="menuEntryCopyAttribute"/>
|
||||
<addaction name="menuEntryTotp"/>
|
||||
<addaction name="actionEntryAutoType"/>
|
||||
<addaction name="actionEntryOpenUrl"/>
|
||||
<addaction name="actionEntryEdit"/>
|
||||
|
|
@ -523,6 +535,21 @@
|
|||
<string>Re&pair database</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEntryTotp">
|
||||
<property name="text">
|
||||
<string>Show TOTP</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEntrySetupTotp">
|
||||
<property name="text">
|
||||
<string>Setup TOTP</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionEntryCopyTotp">
|
||||
<property name="text">
|
||||
<string>Copy &TOTP</string>
|
||||
</property>
|
||||
</action>
|
||||
<action name="actionGroupEmptyRecycleBin">
|
||||
<property name="text">
|
||||
<string>Empty recycle bin</string>
|
||||
|
|
|
|||
101
src/gui/SetupTotpDialog.cpp
Normal file
101
src/gui/SetupTotpDialog.cpp
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Weslly Honorato <weslly@protonmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SetupTotpDialog.h"
|
||||
#include "ui_SetupTotpDialog.h"
|
||||
#include "totp/totp.h"
|
||||
|
||||
|
||||
SetupTotpDialog::SetupTotpDialog(DatabaseWidget* parent, Entry* entry)
|
||||
: QDialog(parent)
|
||||
, m_ui(new Ui::SetupTotpDialog())
|
||||
{
|
||||
m_entry = entry;
|
||||
m_parent = parent;
|
||||
|
||||
m_ui->setupUi(this);
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
this->setFixedSize(this->sizeHint());
|
||||
|
||||
connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(close()));
|
||||
connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(setupTotp()));
|
||||
connect(m_ui->customSettingsCheckBox, SIGNAL(toggled(bool)), SLOT(toggleCustom(bool)));
|
||||
}
|
||||
|
||||
|
||||
void SetupTotpDialog::setupTotp()
|
||||
{
|
||||
quint8 digits;
|
||||
|
||||
if (m_ui->radio8Digits->isChecked()) {
|
||||
digits = 8;
|
||||
} else {
|
||||
digits = 6;
|
||||
}
|
||||
|
||||
quint8 step = m_ui->stepSpinBox->value();
|
||||
QString seed = m_ui->seedEdit->text();
|
||||
m_entry->setTotp(seed, step, digits);
|
||||
emit m_parent->entrySelectionChanged();
|
||||
close();
|
||||
}
|
||||
|
||||
void SetupTotpDialog::toggleCustom(bool status)
|
||||
{
|
||||
m_ui->digitsLabel->setEnabled(status);
|
||||
m_ui->radio6Digits->setEnabled(status);
|
||||
m_ui->radio8Digits->setEnabled(status);
|
||||
|
||||
m_ui->stepLabel->setEnabled(status);
|
||||
m_ui->stepSpinBox->setEnabled(status);
|
||||
}
|
||||
|
||||
|
||||
void SetupTotpDialog::setSeed(QString value)
|
||||
{
|
||||
m_ui->seedEdit->setText(value);
|
||||
}
|
||||
|
||||
void SetupTotpDialog::setStep(quint8 step)
|
||||
{
|
||||
m_ui->stepSpinBox->setValue(step);
|
||||
|
||||
if (step != QTotp::defaultStep) {
|
||||
m_ui->customSettingsCheckBox->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
void SetupTotpDialog::setDigits(quint8 digits)
|
||||
{
|
||||
if (digits == 8) {
|
||||
m_ui->radio8Digits->setChecked(true);
|
||||
m_ui->radio6Digits->setChecked(false);
|
||||
} else {
|
||||
m_ui->radio6Digits->setChecked(true);
|
||||
m_ui->radio8Digits->setChecked(false);
|
||||
}
|
||||
|
||||
if (digits != QTotp::defaultDigits) {
|
||||
m_ui->customSettingsCheckBox->setChecked(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
SetupTotpDialog::~SetupTotpDialog()
|
||||
{
|
||||
}
|
||||
54
src/gui/SetupTotpDialog.h
Normal file
54
src/gui/SetupTotpDialog.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Weslly Honorato <weslly@protonmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSX_SETUPTOTPDIALOG_H
|
||||
#define KEEPASSX_SETUPTOTPDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QScopedPointer>
|
||||
#include "core/Entry.h"
|
||||
#include "core/Database.h"
|
||||
#include "gui/DatabaseWidget.h"
|
||||
|
||||
namespace Ui {
|
||||
class SetupTotpDialog;
|
||||
}
|
||||
|
||||
class SetupTotpDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit SetupTotpDialog(DatabaseWidget* parent = nullptr, Entry* entry = nullptr);
|
||||
~SetupTotpDialog();
|
||||
void setSeed(QString value);
|
||||
void setStep(quint8 step);
|
||||
void setDigits(quint8 digits);
|
||||
|
||||
private Q_SLOTS:
|
||||
void toggleCustom(bool status);
|
||||
void setupTotp();
|
||||
|
||||
private:
|
||||
QScopedPointer<Ui::SetupTotpDialog> m_ui;
|
||||
|
||||
protected:
|
||||
Entry* m_entry;
|
||||
DatabaseWidget* m_parent;
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_SETUPTOTPDIALOG_H
|
||||
137
src/gui/SetupTotpDialog.ui
Normal file
137
src/gui/SetupTotpDialog.ui
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>SetupTotpDialog</class>
|
||||
<widget class="QDialog" name="SetupTotpDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>282</width>
|
||||
<height>257</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Setup TOTP</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Key:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="seedEdit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="customSettingsCheckBox">
|
||||
<property name="text">
|
||||
<string>Use custom settings</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>Note: Change these settings only if you know what you are doing.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout_3">
|
||||
<property name="fieldGrowthPolicy">
|
||||
<enum>QFormLayout::ExpandingFieldsGrow</enum>
|
||||
</property>
|
||||
<property name="rowWrapPolicy">
|
||||
<enum>QFormLayout::DontWrapRows</enum>
|
||||
</property>
|
||||
<property name="labelAlignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTop|Qt::AlignTrailing</set>
|
||||
</property>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="stepLabel">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Time step:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QRadioButton" name="radio8Digits">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>8 digits</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QRadioButton" name="radio6Digits">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>6 digits</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="digitsLabel">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Code size:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QSpinBox" name="stepSpinBox">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="suffix">
|
||||
<string> sec</string>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>60</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>30</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
100
src/gui/TotpDialog.cpp
Normal file
100
src/gui/TotpDialog.cpp
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Weslly Honorato <weslly@protonmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "TotpDialog.h"
|
||||
#include "ui_TotpDialog.h"
|
||||
|
||||
#include "core/Config.h"
|
||||
#include "core/Entry.h"
|
||||
#include "gui/DatabaseWidget.h"
|
||||
#include "gui/Clipboard.h"
|
||||
|
||||
#include <QTimer>
|
||||
#include <QDateTime>
|
||||
#include <QPushButton>
|
||||
|
||||
|
||||
TotpDialog::TotpDialog(DatabaseWidget* parent, Entry* entry)
|
||||
: QDialog(parent)
|
||||
, m_ui(new Ui::TotpDialog())
|
||||
{
|
||||
m_entry = entry;
|
||||
m_parent = parent;
|
||||
m_step = m_entry->totpStep();
|
||||
|
||||
m_ui->setupUi(this);
|
||||
|
||||
uCounter = resetCounter();
|
||||
updateProgressBar();
|
||||
|
||||
QTimer *timer = new QTimer(this);
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(updateProgressBar()));
|
||||
connect(timer, SIGNAL(timeout()), this, SLOT(updateSeconds()));
|
||||
timer->start(m_step * 10);
|
||||
|
||||
updateTotp();
|
||||
|
||||
setAttribute(Qt::WA_DeleteOnClose);
|
||||
|
||||
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Copy"));
|
||||
|
||||
connect(m_ui->buttonBox, SIGNAL(rejected()), SLOT(close()));
|
||||
connect(m_ui->buttonBox, SIGNAL(accepted()), SLOT(copyToClipboard()));
|
||||
}
|
||||
|
||||
void TotpDialog::copyToClipboard()
|
||||
{
|
||||
clipboard()->setText(m_entry->totp());
|
||||
if (config()->get("MinimizeOnCopy").toBool()) {
|
||||
m_parent->window()->showMinimized();
|
||||
}
|
||||
}
|
||||
|
||||
void TotpDialog::updateProgressBar()
|
||||
{
|
||||
if (uCounter < 100) {
|
||||
m_ui->progressBar->setValue(100 - uCounter);
|
||||
m_ui->progressBar->update();
|
||||
uCounter++;
|
||||
} else {
|
||||
updateTotp();
|
||||
uCounter = resetCounter();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TotpDialog::updateSeconds()
|
||||
{
|
||||
uint epoch = QDateTime::currentDateTime().toTime_t() - 1;
|
||||
m_ui->timerLabel->setText(tr("Expires in") + " <b>" + QString::number(m_step - (epoch % m_step)) + "</b> " + tr("seconds"));
|
||||
}
|
||||
|
||||
void TotpDialog::updateTotp()
|
||||
{
|
||||
m_ui->totpLabel->setText(m_entry->totp());
|
||||
}
|
||||
|
||||
double TotpDialog::resetCounter()
|
||||
{
|
||||
uint epoch = QDateTime::currentDateTime().toTime_t();
|
||||
double counter = qRound(static_cast<double>(epoch % m_step) / m_step * 100);
|
||||
return counter;
|
||||
}
|
||||
|
||||
TotpDialog::~TotpDialog()
|
||||
{
|
||||
}
|
||||
56
src/gui/TotpDialog.h
Normal file
56
src/gui/TotpDialog.h
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (C) 2017 Weslly Honorato <weslly@protonmail.com>
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 or (at your option)
|
||||
* version 3 of the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef KEEPASSX_TOTPDIALOG_H
|
||||
#define KEEPASSX_TOTPDIALOG_H
|
||||
|
||||
#include <QDialog>
|
||||
#include <QScopedPointer>
|
||||
#include "core/Entry.h"
|
||||
#include "core/Database.h"
|
||||
#include "gui/DatabaseWidget.h"
|
||||
|
||||
namespace Ui {
|
||||
class TotpDialog;
|
||||
}
|
||||
|
||||
class TotpDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit TotpDialog(DatabaseWidget* parent = nullptr, Entry* entry = nullptr);
|
||||
~TotpDialog();
|
||||
|
||||
private:
|
||||
double uCounter;
|
||||
quint8 m_step;
|
||||
QScopedPointer<Ui::TotpDialog> m_ui;
|
||||
|
||||
private Q_SLOTS:
|
||||
void updateTotp();
|
||||
void updateProgressBar();
|
||||
void updateSeconds();
|
||||
void copyToClipboard();
|
||||
double resetCounter();
|
||||
|
||||
protected:
|
||||
Entry* m_entry;
|
||||
DatabaseWidget* m_parent;
|
||||
};
|
||||
|
||||
#endif // KEEPASSX_TOTPDIALOG_H
|
||||
60
src/gui/TotpDialog.ui
Normal file
60
src/gui/TotpDialog.ui
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>TotpDialog</class>
|
||||
<widget class="QWidget" name="TotpDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>264</width>
|
||||
<height>194</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Timed Password</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="totpLabel">
|
||||
<property name="font">
|
||||
<font>
|
||||
<pointsize>53</pointsize>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>000000</string>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignCenter</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QProgressBar" name="progressBar">
|
||||
<property name="value">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="textVisible">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="timerLabel">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::Close|QDialogButtonBox::Ok</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
Loading…
Add table
Add a link
Reference in a new issue