fix: audit findings — security, i18n, validation, dead code (v0.3.2)

Quality:
- Q-5: Allow relative session commands (e.g. niri-session), greetd resolves PATH
- Q-3: Socket read+write timeouts with proper error logging
- Q-2: Remove unused PowerError::Timeout variant
- Q-M1: i18n for all login_worker error messages (new: unexpected_greetd_response)
- Q-M2: Explicit INVALID_LIST_POSITION check in session dropdown
- Q-M4: Log SVG loader.close() errors instead of silencing
- Q-M6: Testable persistence functions with proper roundtrip tests

Security:
- S-2: Validate GTK theme name (alphanumeric, _, -, +, . only)
- S-3: Log file created with mode 0o640
- S-4: Cache files (last-user, last-session) created with mode 0o600

Performance:
- P-3: Single symlink_metadata() call instead of exists() + is_symlink()
- P-4: Avoid Vec allocation in IPC send_message (two write_all calls)

Config:
- Update example GTK theme to Colloid-Catppuccin
This commit is contained in:
2026-03-28 00:37:35 +01:00
parent 4fa0dd0ead
commit 0d4a1b035a
8 changed files with 186 additions and 56 deletions
+4
View File
@@ -30,6 +30,7 @@ pub struct Strings {
pub shutdown_failed: &'static str,
pub connection_error: &'static str,
pub socket_error: &'static str,
pub unexpected_greetd_response: &'static str,
// Templates (use .replace("{n}", &count.to_string()))
pub faillock_attempts_remaining: &'static str,
@@ -54,6 +55,7 @@ const STRINGS_DE: Strings = Strings {
shutdown_failed: "Herunterfahren fehlgeschlagen",
connection_error: "Verbindungsfehler",
socket_error: "Socket-Fehler",
unexpected_greetd_response: "Unerwartete Antwort von greetd",
faillock_attempts_remaining: "Noch {n} Versuch(e) vor Kontosperrung!",
faillock_locked: "Konto ist möglicherweise gesperrt",
};
@@ -76,6 +78,7 @@ const STRINGS_EN: Strings = Strings {
shutdown_failed: "Shutdown failed",
connection_error: "Connection error",
socket_error: "Socket error",
unexpected_greetd_response: "Unexpected response from greetd",
faillock_attempts_remaining: "{n} attempt(s) remaining before lockout!",
faillock_locked: "Account may be locked",
};
@@ -281,6 +284,7 @@ mod tests {
assert!(!s.shutdown_failed.is_empty(), "{locale}: shutdown_failed");
assert!(!s.faillock_attempts_remaining.is_empty(), "{locale}: faillock_attempts_remaining");
assert!(!s.faillock_locked.is_empty(), "{locale}: faillock_locked");
assert!(!s.unexpected_greetd_response.is_empty(), "{locale}: unexpected_greetd_response");
}
}