mirror of
https://github.com/keepassxreboot/keepassxc.git
synced 2025-12-04 15:39:34 +01:00
committed by
Janek Bevendorff
parent
9526f42536
commit
d8f7d602b4
@@ -32,6 +32,7 @@
|
||||
#include "core/Global.h"
|
||||
#include "core/Resources.h"
|
||||
#include "core/Tools.h"
|
||||
#include "core/Totp.h"
|
||||
#include "gui/MainWindow.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "gui/osutils/OSUtils.h"
|
||||
@@ -311,9 +312,6 @@ void AutoType::executeAutoTypeActions(const Entry* entry,
|
||||
// Restore executor mode
|
||||
m_executor->mode = mode;
|
||||
|
||||
int delay = qMax(100, config()->get(Config::AutoTypeStartDelay).toInt());
|
||||
Tools::wait(delay);
|
||||
|
||||
// Grab the current active window after everything settles
|
||||
if (window == 0) {
|
||||
window = m_plugin->activeWindow();
|
||||
@@ -345,7 +343,8 @@ void AutoType::executeAutoTypeActions(const Entry* entry,
|
||||
break;
|
||||
}
|
||||
|
||||
Tools::wait(delay);
|
||||
// Retry wait delay
|
||||
Tools::wait(100);
|
||||
}
|
||||
|
||||
// Last action failed to complete, cancel the rest of the sequence
|
||||
@@ -546,10 +545,14 @@ AutoType::parseSequence(const QString& entrySequence, const Entry* entry, QStrin
|
||||
const int maxTypeDelay = 500;
|
||||
const int maxWaitDelay = 10000;
|
||||
const int maxRepetition = 100;
|
||||
int currentTypingDelay = qBound(0, config()->get(Config::AutoTypeDelay).toInt(), maxTypeDelay);
|
||||
int cumulativeDelay = qBound(0, config()->get(Config::AutoTypeStartDelay).toInt(), maxWaitDelay);
|
||||
|
||||
// Initial actions include start delay and initial inter-key delay
|
||||
QList<QSharedPointer<AutoTypeAction>> actions;
|
||||
actions << QSharedPointer<AutoTypeBegin>::create();
|
||||
actions << QSharedPointer<AutoTypeDelay>::create(qMax(0, config()->get(Config::AutoTypeDelay).toInt()), true);
|
||||
actions << QSharedPointer<AutoTypeDelay>::create(currentTypingDelay, true);
|
||||
actions << QSharedPointer<AutoTypeDelay>::create(cumulativeDelay);
|
||||
|
||||
// Replace escaped braces with a template for easier regex
|
||||
QString sequence = entrySequence;
|
||||
@@ -565,7 +568,7 @@ AutoType::parseSequence(const QString& entrySequence, const Entry* entry, QStrin
|
||||
// Group 1 = modifier key (opt)
|
||||
// Group 2 = full placeholder
|
||||
// Group 3 = inner placeholder (allows nested placeholders)
|
||||
// Group 4 = repeat (opt)
|
||||
// Group 4 = repeat / delay time (opt)
|
||||
// Group 5 = character
|
||||
QRegularExpression regex("([+%^#]*)(?:({((?>[^{}]+?|(?2))+?)(?:\\s+(\\d+))?})|(.))");
|
||||
auto results = regex.globalMatch(sequence);
|
||||
@@ -627,19 +630,23 @@ AutoType::parseSequence(const QString& entrySequence, const Entry* entry, QStrin
|
||||
}
|
||||
actions << QSharedPointer<AutoTypeDelay>::create(qBound(0, delay, maxTypeDelay), true);
|
||||
} else if (placeholder == "delay") {
|
||||
// Mid typing delay (wait)
|
||||
// Mid typing delay (wait), repeat represents the desired delay in milliseconds
|
||||
if (repeat > maxWaitDelay) {
|
||||
error = tr("Very long delay detected, max is %1: %2").arg(maxWaitDelay).arg(fullPlaceholder);
|
||||
return {};
|
||||
}
|
||||
cumulativeDelay += repeat;
|
||||
actions << QSharedPointer<AutoTypeDelay>::create(qBound(0, repeat, maxWaitDelay));
|
||||
} else if (placeholder == "clearfield") {
|
||||
// Platform-specific field clearing
|
||||
actions << QSharedPointer<AutoTypeClearField>::create();
|
||||
} else if (placeholder == "totp") {
|
||||
if (entry->hasValidTotp()) {
|
||||
// Entry totp (requires special handling)
|
||||
QString totp = entry->totp();
|
||||
// Calculate TOTP at the time of typing including delays
|
||||
bool isValid = false;
|
||||
auto time =
|
||||
Clock::currentSecondsSinceEpoch() + (cumulativeDelay + currentTypingDelay * actions.count()) / 1000;
|
||||
auto totp = Totp::generateTotp(entry->totpSettings(), &isValid, time);
|
||||
for (const auto& ch : totp) {
|
||||
actions << QSharedPointer<AutoTypeKey>::create(ch);
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "core/Config.h"
|
||||
#include "core/Group.h"
|
||||
#include "core/Resources.h"
|
||||
#include "core/Totp.h"
|
||||
#include "crypto/Crypto.h"
|
||||
#include "gui/MessageBox.h"
|
||||
#include "gui/osutils/OSUtils.h"
|
||||
@@ -73,6 +74,9 @@ void TestAutoType::init()
|
||||
association.window = "custom window";
|
||||
association.sequence = "{username}association{password}";
|
||||
m_entry1->autoTypeAssociations()->add(association);
|
||||
// Create a totp with a short time step to test delayed typing
|
||||
auto totpSettings = Totp::createSettings("NNSWK4DBONZXQYZB", Totp::DEFAULT_DIGITS, 2);
|
||||
m_entry1->setTotp(totpSettings);
|
||||
|
||||
m_entry2 = new Entry();
|
||||
m_entry2->setGroup(m_group);
|
||||
@@ -468,3 +472,24 @@ void TestAutoType::testAutoTypeEmptyWindowAssociation()
|
||||
assoc = m_entry6->autoTypeSequences("Some Other Window");
|
||||
QVERIFY(assoc.isEmpty());
|
||||
}
|
||||
|
||||
void TestAutoType::testAutoTypeTotpDelay()
|
||||
{
|
||||
// Get the TOTP time step in milliseconds
|
||||
auto totpStep = m_entry1->totpSettings()->step * 1000;
|
||||
auto sequence = QString("{TOTP} {DELAY %1}{TOTP}").arg(QString::number(totpStep * 2));
|
||||
|
||||
// Test 1: Sequence with a 3 second delay before TOTP
|
||||
m_autoType->performAutoTypeWithSequence(m_entry1, sequence);
|
||||
auto typedChars = m_test->actionChars();
|
||||
|
||||
// The typed TOTP should be different between the first and second one
|
||||
auto totpParts = m_test->actionChars().split(' ');
|
||||
QCOMPARE(totpParts.size(), 2);
|
||||
QCOMPARE(totpParts[0].size(), m_entry1->totpSettings()->digits);
|
||||
QCOMPARE(totpParts[1].size(), m_entry1->totpSettings()->digits);
|
||||
QVERIFY2(totpParts[0] != totpParts[1],
|
||||
QString("Typed TOTP (%1) should differ from current TOTP (%2) due to delay")
|
||||
.arg(totpParts[0], totpParts[1])
|
||||
.toLatin1());
|
||||
}
|
||||
|
||||
@@ -52,6 +52,7 @@ private slots:
|
||||
void testAutoTypeSyntaxChecks();
|
||||
void testAutoTypeEffectiveSequences();
|
||||
void testAutoTypeEmptyWindowAssociation();
|
||||
void testAutoTypeTotpDelay();
|
||||
|
||||
private:
|
||||
AutoTypePlatformInterface* m_platform;
|
||||
|
||||
Reference in New Issue
Block a user