Skip to content

Commit

Permalink
auth: fixup prompt and fail placeholder substitution
Browse files Browse the repository at this point in the history
  • Loading branch information
PaideiaDilemma committed Jan 6, 2025
1 parent de844d3 commit 495eaa8
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 32 deletions.
23 changes: 20 additions & 3 deletions src/auth/Auth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,21 +40,38 @@ bool CAuth::checkWaiting() {
return false;
}

std::string CAuth::getInlineFeedback() {
std::string CAuth::getLastFailText() {
std::optional<std::string> firstFeedback = std::nullopt;
for (const auto& i : m_vImpls) {
const auto FEEDBACK = (m_bDisplayFailText) ? i->getLastFailText() : i->getLastPrompt();
const auto FEEDBACK = i->getLastFailText();
if (!FEEDBACK.has_value())
continue;

if (i->getImplType() == m_eLastActiveImpl)
return FEEDBACK.value();

if (!firstFeedback.has_value())
firstFeedback = FEEDBACK;
}

return firstFeedback.value_or("");
}

std::string CAuth::getLastPrompt() {
std::optional<std::string> firstFeedback = std::nullopt;
for (const auto& i : m_vImpls) {
const auto FEEDBACK = i->getLastPrompt();
if (!FEEDBACK.has_value())
continue;

if (i->getImplType() == m_eLastActiveImpl)
return FEEDBACK.value();

if (!firstFeedback.has_value())
firstFeedback = FEEDBACK;
}

return firstFeedback.value_or("Ups, no authentication feedack");
return firstFeedback.value_or("");
}

std::optional<std::string> CAuth::getFailText(eAuthImplementations implType) {
Expand Down
8 changes: 4 additions & 4 deletions src/auth/Auth.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ class CAuth {
void submitInput(const std::string& input);
bool checkWaiting();

// Used by the PasswordInput field. We are constraint to a single line for the authentication feedback there.
// Based on m_bDisplayFailText, this will return either the fail text or the prompt.
// Based on m_eLastActiveImpl, it will select the implementation.
std::string getInlineFeedback();
// Gets the last fail text from m_eLastActiveImpl or the first one found.
std::string getLastFailText();
// Gets the last promt from m_eLastActiveImpl or the first one found.
std::string getLastPrompt();

std::optional<std::string> getFailText(eAuthImplementations implType);
std::optional<std::string> getPrompt(eAuthImplementations implType);
Expand Down
12 changes: 4 additions & 8 deletions src/auth/Fingerprint.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ bool CFingerprint::createDeviceProxy() {
}

void CFingerprint::handleVerifyStatus(const std::string& result, bool done) {
g_pAuth->postActivity(AUTH_IMPL_FINGERPRINT);
Debug::log(LOG, "fprint: handling status {}", result);
auto matchResult = s_mapStringToTestType[result];
bool authenticated = false;
Expand All @@ -168,14 +167,9 @@ void CFingerprint::handleVerifyStatus(const std::string& result, bool done) {
m_sPrompt = "";
m_sFailureReason = "Fingerprint auth disabled (too many failed attempts)";
} else {
done = false;
done = false;
static const auto RETRYDELAY = **(Hyprlang::INT* const*)(g_pConfigManager->getValuePtr("auth:fingerprint:retry_delay"));
g_pHyprlock->addTimer(
std::chrono::milliseconds(RETRYDELAY),
[](std::shared_ptr<CTimer> self, void* data) {
((CFingerprint*)data)->startVerify(true);
},
this);
g_pHyprlock->addTimer(std::chrono::milliseconds(RETRYDELAY), [](std::shared_ptr<CTimer> self, void* data) { ((CFingerprint*)data)->startVerify(true); }, this);
}
break;
case MATCH_UNKNOWN_ERROR:
Expand Down Expand Up @@ -217,6 +211,8 @@ void CFingerprint::handleVerifyStatus(const std::string& result, bool done) {
break;
}

g_pAuth->postActivity(AUTH_IMPL_FINGERPRINT);

if (!authenticated && !retry)
g_pAuth->enqueueFail();

Expand Down
42 changes: 26 additions & 16 deletions src/renderer/widgets/IWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -118,16 +118,14 @@ static void replaceAllLayout(std::string& str) {
}
}

static bool logMissingTzOnce = true;
static bool logMissingTzOnce = true;
static std::chrono::hh_mm_ss<std::chrono::system_clock::duration> getTime() {
const std::chrono::time_zone* pCurrentTz = nullptr;
try {
auto name = std::getenv("TZ");
if (name)
pCurrentTz = std::chrono::locate_zone(name);
} catch (std::runtime_error&) {
Debug::log(WARN, "Invalid TZ value. Falling back to current timezone!");
}
} catch (std::runtime_error&) { Debug::log(WARN, "Invalid TZ value. Falling back to current timezone!"); }

if (!pCurrentTz)
pCurrentTz = std::chrono::current_zone();
Expand All @@ -150,15 +148,15 @@ static std::chrono::hh_mm_ss<std::chrono::system_clock::duration> getTime() {

static std::string getTime24h() {
const auto HHMMSS = getTime();
const auto HRS = HHMMSS.hours().count();
const auto MINS = HHMMSS.minutes().count();
const auto HRS = HHMMSS.hours().count();
const auto MINS = HHMMSS.minutes().count();
return (HRS < 10 ? "0" : "") + std::to_string(HRS) + ":" + (MINS < 10 ? "0" : "") + std::to_string(MINS);
}

static std::string getTime12h() {
const auto HHMMSS = getTime();
const auto HRS = HHMMSS.hours().count();
const auto MINS = HHMMSS.minutes().count();
const auto HRS = HHMMSS.hours().count();
const auto MINS = HHMMSS.minutes().count();
return (HRS == 12 || HRS == 0 ? "12" : (HRS % 12 < 10 ? "0" : "") + std::to_string(HRS % 12)) + ":" + (MINS < 10 ? "0" : "") + std::to_string(MINS) +
(HRS < 12 ? " AM" : " PM");
}
Expand Down Expand Up @@ -190,25 +188,37 @@ IWidget::SFormatResult IWidget::formatString(std::string in) {
result.updateEveryMs = result.updateEveryMs != 0 && result.updateEveryMs < 1000 ? result.updateEveryMs : 1000;
}

if (in.contains("$ATTEMPTS")) {
replaceAllAttempts(in);
result.allowForceUpdate = true;
}

if (in.contains("$LAYOUT")) {
replaceAllLayout(in);
result.allowForceUpdate = true;
}

if (in.contains("$FAIL")) {
const auto FAIL = g_pAuth->getFailText(AUTH_IMPL_PAM);
replaceInString(in, "$FAIL", FAIL.value_or(""));
const auto FAIL = g_pAuth->getLastFailText();
replaceInString(in, "$FAIL", FAIL);
result.allowForceUpdate = true;
}

if (in.contains("$PROMPT")) {
const auto PROMPT = g_pAuth->getPrompt(AUTH_IMPL_PAM);
replaceInString(in, "$PROMPT", PROMPT.value_or(""));
const auto PROMPT = g_pAuth->getLastPrompt();
replaceInString(in, "$PROMPT", PROMPT);
result.allowForceUpdate = true;
}

if (in.contains("$ATTEMPTS")) {
replaceAllAttempts(in);
if (in.contains("$PAMFAIL")) {
const auto FAIL = g_pAuth->getFailText(AUTH_IMPL_PAM);
replaceInString(in, "$PAMFAIL", FAIL.value_or(""));
result.allowForceUpdate = true;
}

if (in.contains("$LAYOUT")) {
replaceAllLayout(in);
if (in.contains("$PAMPROMPT")) {
const auto PROMPT = g_pAuth->getPrompt(AUTH_IMPL_PAM);
replaceInString(in, "$PAMPROMPT", PROMPT.value_or(""));
result.allowForceUpdate = true;
}

Expand Down
6 changes: 5 additions & 1 deletion src/renderer/widgets/PasswordInputField.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -304,9 +304,13 @@ void CPasswordInputField::updatePlaceholder() {
return;
}

const auto AUTHFEEDBACK = g_pAuth->getInlineFeedback();
// This and placeholder.lastAuthFeedback is just to be able to do an early exit below.
const auto AUTHFEEDBACK = (displayFail) ? g_pAuth->getLastFailText() : g_pAuth->getLastPrompt();
const auto ALLOWCOLORSWAP = outThick == 0 && colorConfig.swapFont;

if (AUTHFEEDBACK.empty())
return;

if (!ALLOWCOLORSWAP && placeholder.lastAuthFeedback == AUTHFEEDBACK && g_pAuth->m_iFailedAttempts == placeholder.failedAttempts)
return;

Expand Down

0 comments on commit 495eaa8

Please sign in to comment.