mirror of
https://github.com/hyprwm/hyprlock.git
synced 2025-05-13 05:40:42 +01:00
fingerprint: better feedback and don't clear input field on retry (#613)
This commit is contained in:
parent
181294c4d8
commit
d212f4cc10
3 changed files with 58 additions and 22 deletions
|
@ -13,7 +13,6 @@ static const auto FPRINT = sdbus::ServiceName{"net.reactivated.Fprint"};
|
||||||
static const auto DEVICE = sdbus::ServiceName{"net.reactivated.Fprint.Device"};
|
static const auto DEVICE = sdbus::ServiceName{"net.reactivated.Fprint.Device"};
|
||||||
static const auto MANAGER = sdbus::ServiceName{"net.reactivated.Fprint.Manager"};
|
static const auto MANAGER = sdbus::ServiceName{"net.reactivated.Fprint.Manager"};
|
||||||
static const auto LOGIN_MANAGER = sdbus::ServiceName{"org.freedesktop.login1.Manager"};
|
static const auto LOGIN_MANAGER = sdbus::ServiceName{"org.freedesktop.login1.Manager"};
|
||||||
static const auto RETRY_MESSAGE = "Could not match fingerprint. Try again.";
|
|
||||||
|
|
||||||
enum MatchResult {
|
enum MatchResult {
|
||||||
MATCH_INVALID = 0,
|
MATCH_INVALID = 0,
|
||||||
|
@ -81,10 +80,14 @@ void CFingerprint::handleInput(const std::string& input) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> CFingerprint::getLastFailText() {
|
std::optional<std::string> CFingerprint::getLastFailText() {
|
||||||
return m_sDBUSState.message.empty() ? std::nullopt : std::optional(m_sDBUSState.message);
|
if (!m_sFailureReason.empty())
|
||||||
|
return std::optional(m_sFailureReason);
|
||||||
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<std::string> CFingerprint::getLastPrompt() {
|
std::optional<std::string> CFingerprint::getLastPrompt() {
|
||||||
|
if (!m_sPrompt.empty())
|
||||||
|
return std::optional(m_sPrompt);
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +143,8 @@ bool CFingerprint::createDeviceProxy() {
|
||||||
bool isPresent = presentVariant.get<bool>();
|
bool isPresent = presentVariant.get<bool>();
|
||||||
if (!isPresent)
|
if (!isPresent)
|
||||||
return;
|
return;
|
||||||
m_sDBUSState.message = m_sFingerprintPresent;
|
m_sPrompt = m_sFingerprintPresent;
|
||||||
|
m_sFailureReason = "";
|
||||||
g_pHyprlock->enqueueForceUpdateTimers();
|
g_pHyprlock->enqueueForceUpdateTimers();
|
||||||
} catch (std::out_of_range& e) {}
|
} catch (std::out_of_range& e) {}
|
||||||
});
|
});
|
||||||
|
@ -153,6 +157,7 @@ void CFingerprint::handleVerifyStatus(const std::string& result, bool done) {
|
||||||
Debug::log(LOG, "fprint: handling status {}", result);
|
Debug::log(LOG, "fprint: handling status {}", result);
|
||||||
auto matchResult = s_mapStringToTestType[result];
|
auto matchResult = s_mapStringToTestType[result];
|
||||||
bool authenticated = false;
|
bool authenticated = false;
|
||||||
|
bool retry = false;
|
||||||
if (m_sDBUSState.sleeping && matchResult != MATCH_DISCONNECTED)
|
if (m_sDBUSState.sleeping && matchResult != MATCH_DISCONNECTED)
|
||||||
return;
|
return;
|
||||||
switch (matchResult) {
|
switch (matchResult) {
|
||||||
|
@ -160,34 +165,53 @@ void CFingerprint::handleVerifyStatus(const std::string& result, bool done) {
|
||||||
case MATCH_NO_MATCH:
|
case MATCH_NO_MATCH:
|
||||||
stopVerify();
|
stopVerify();
|
||||||
if (m_sDBUSState.retries >= 3) {
|
if (m_sDBUSState.retries >= 3) {
|
||||||
m_sDBUSState.message = "Fingerprint auth disabled (too many failed attempts)";
|
m_sPrompt = "";
|
||||||
|
m_sFailureReason = "Fingerprint auth disabled (too many failed attempts)";
|
||||||
} else {
|
} else {
|
||||||
done = false;
|
done = false;
|
||||||
startVerify(true);
|
startVerify(true);
|
||||||
m_sDBUSState.message = "Fingerprint not matched";
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case MATCH_UNKNOWN_ERROR:
|
case MATCH_UNKNOWN_ERROR:
|
||||||
stopVerify();
|
stopVerify();
|
||||||
m_sDBUSState.message = "Fingerprint auth disabled (unknown error)";
|
m_sPrompt = "";
|
||||||
|
m_sFailureReason = "Fingerprint auth disabled (unknown error)";
|
||||||
break;
|
break;
|
||||||
case MATCH_MATCHED:
|
case MATCH_MATCHED:
|
||||||
stopVerify();
|
stopVerify();
|
||||||
m_sDBUSState.message = "";
|
m_sPrompt = "";
|
||||||
authenticated = true;
|
m_sFailureReason = "";
|
||||||
|
authenticated = true;
|
||||||
g_pAuth->enqueueUnlock();
|
g_pAuth->enqueueUnlock();
|
||||||
break;
|
break;
|
||||||
case MATCH_RETRY: m_sDBUSState.message = "Please retry fingerprint scan"; break;
|
case MATCH_RETRY:
|
||||||
case MATCH_SWIPE_TOO_SHORT: m_sDBUSState.message = "Swipe too short - try again"; break;
|
retry = true;
|
||||||
case MATCH_FINGER_NOT_CENTERED: m_sDBUSState.message = "Finger not centered - try again"; break;
|
m_sPrompt = "Please retry fingerprint scan";
|
||||||
case MATCH_REMOVE_AND_RETRY: m_sDBUSState.message = "Remove your finger and try again"; break;
|
m_sFailureReason = "";
|
||||||
|
break;
|
||||||
|
case MATCH_SWIPE_TOO_SHORT:
|
||||||
|
retry = true;
|
||||||
|
m_sPrompt = "Swipe too short - try again";
|
||||||
|
m_sFailureReason = "";
|
||||||
|
break;
|
||||||
|
case MATCH_FINGER_NOT_CENTERED:
|
||||||
|
retry = true;
|
||||||
|
m_sPrompt = "Finger not centered - try again";
|
||||||
|
m_sFailureReason = "";
|
||||||
|
break;
|
||||||
|
case MATCH_REMOVE_AND_RETRY:
|
||||||
|
retry = true;
|
||||||
|
m_sPrompt = "Remove your finger and try again";
|
||||||
|
m_sFailureReason = "";
|
||||||
|
break;
|
||||||
case MATCH_DISCONNECTED:
|
case MATCH_DISCONNECTED:
|
||||||
m_sDBUSState.message = "Fingerprint device disconnected";
|
m_sPrompt = "";
|
||||||
m_sDBUSState.abort = true;
|
m_sFailureReason = "Fingerprint device disconnected";
|
||||||
|
m_sDBUSState.abort = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!authenticated)
|
if (!authenticated && !retry)
|
||||||
g_pAuth->enqueueFail();
|
g_pAuth->enqueueFail();
|
||||||
|
|
||||||
if (done || m_sDBUSState.abort)
|
if (done || m_sDBUSState.abort)
|
||||||
|
@ -218,15 +242,20 @@ void CFingerprint::startVerify(bool isRetry) {
|
||||||
m_sDBUSState.device->callMethodAsync("VerifyStart").onInterface(DEVICE).withArguments(finger).uponReplyInvoke([this, isRetry](std::optional<sdbus::Error> e) {
|
m_sDBUSState.device->callMethodAsync("VerifyStart").onInterface(DEVICE).withArguments(finger).uponReplyInvoke([this, isRetry](std::optional<sdbus::Error> e) {
|
||||||
if (e) {
|
if (e) {
|
||||||
Debug::log(WARN, "fprint: could not start verifying, {}", e->what());
|
Debug::log(WARN, "fprint: could not start verifying, {}", e->what());
|
||||||
if (isRetry)
|
if (isRetry) {
|
||||||
m_sDBUSState.message = "Fingerprint auth disabled (failed to restart)";
|
m_sPrompt = "";
|
||||||
|
m_sFailureReason = "Fingerprint auth disabled (failed to restart)";
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Debug::log(LOG, "fprint: started verifying");
|
Debug::log(LOG, "fprint: started verifying");
|
||||||
if (isRetry) {
|
if (isRetry) {
|
||||||
m_sDBUSState.retries++;
|
m_sDBUSState.retries++;
|
||||||
m_sDBUSState.message = RETRY_MESSAGE;
|
m_sPrompt = "Could not match fingerprint. Try again.";
|
||||||
} else
|
m_sFailureReason = "";
|
||||||
m_sDBUSState.message = m_sFingerprintReady;
|
} else {
|
||||||
|
m_sPrompt = m_sFingerprintReady;
|
||||||
|
m_sFailureReason = "";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g_pHyprlock->enqueueForceUpdateTimers();
|
g_pHyprlock->enqueueForceUpdateTimers();
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,8 +26,6 @@ class CFingerprint : public IAuthImplementation {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct SDBUSState {
|
struct SDBUSState {
|
||||||
std::string message = "";
|
|
||||||
|
|
||||||
std::shared_ptr<sdbus::IConnection> connection;
|
std::shared_ptr<sdbus::IConnection> connection;
|
||||||
std::unique_ptr<sdbus::IProxy> login;
|
std::unique_ptr<sdbus::IProxy> login;
|
||||||
std::unique_ptr<sdbus::IProxy> device;
|
std::unique_ptr<sdbus::IProxy> device;
|
||||||
|
@ -42,6 +40,9 @@ class CFingerprint : public IAuthImplementation {
|
||||||
std::string m_sFingerprintReady;
|
std::string m_sFingerprintReady;
|
||||||
std::string m_sFingerprintPresent;
|
std::string m_sFingerprintPresent;
|
||||||
|
|
||||||
|
std::string m_sPrompt{""};
|
||||||
|
std::string m_sFailureReason{""};
|
||||||
|
|
||||||
void handleVerifyStatus(const std::string& result, const bool done);
|
void handleVerifyStatus(const std::string& result, const bool done);
|
||||||
|
|
||||||
void inhibitSleep();
|
void inhibitSleep();
|
||||||
|
|
|
@ -197,6 +197,12 @@ IWidget::SFormatResult IWidget::formatString(std::string in) {
|
||||||
result.allowForceUpdate = true;
|
result.allowForceUpdate = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (in.contains("$FPRINTPROMPT")) {
|
||||||
|
const auto FPRINTPROMPT = g_pAuth->getPrompt(AUTH_IMPL_FINGERPRINT);
|
||||||
|
replaceInString(in, "$FPRINTPROMPT", FPRINTPROMPT.value_or(""));
|
||||||
|
result.allowForceUpdate = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (in.starts_with("cmd[") && in.contains("]")) {
|
if (in.starts_with("cmd[") && in.contains("]")) {
|
||||||
// this is a command
|
// this is a command
|
||||||
CVarList vars(in.substr(4, in.find_first_of(']') - 4), 0, ',', true);
|
CVarList vars(in.substr(4, in.find_first_of(']') - 4), 0, ',', true);
|
||||||
|
|
Loading…
Reference in a new issue