feat: add optional data wipe after failed password attempts#1794
Open
goncalosamp27 wants to merge 9 commits intobeemdevelopment:masterfrom
Open
feat: add optional data wipe after failed password attempts#1794goncalosamp27 wants to merge 9 commits intobeemdevelopment:masterfrom
goncalosamp27 wants to merge 9 commits intobeemdevelopment:masterfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds an optional security feature to progressively lock out users after consecutive failed unlock attempts and (optionally) wipe the vault after a configurable limit, with settings exposed under Security preferences.
Changes:
- Added Security settings for enabling data wiping and configuring the maximum failed unlock attempts.
- Implemented persisted failed-attempt tracking, progressive lockout with countdown UI, and a “final attempt” warning dialog.
- Reused existing vault deletion/lock+exit flow to wipe the vault when the configured limit is reached.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 10 comments.
Show a summary per file
| File | Description |
|---|---|
| app/src/main/res/xml/preferences_security.xml | Adds new Security preferences (toggle + max-attempts entry). |
| app/src/main/res/values/strings.xml | Adds strings for the new preferences, lockout message, warning dialog, and empty-password validation. |
| app/src/main/res/layout/activity_auth.xml | Adds a lockout countdown message TextView to the auth screen. |
| app/src/main/res/drawable/ic_warning_24.xml | Adds a warning icon used by the “final attempt” dialog. |
| app/src/main/java/com/beemdevelopment/aegis/ui/fragments/preferences/SecurityPreferencesFragment.java | Wires the new preferences to a number picker dialog and persists the selection. |
| app/src/main/java/com/beemdevelopment/aegis/ui/dialogs/Dialogs.java | Adds a number picker dialog for selecting max failed attempts. |
| app/src/main/java/com/beemdevelopment/aegis/ui/AuthActivity.java | Implements failed-attempt persistence, lockout logic/countdown, final-attempt warning, and wipe+exit behavior. |
| app/src/main/java/com/beemdevelopment/aegis/Preferences.java | Adds preference accessors for enabling wipe + max failed attempts. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| private Button _decryptButton; | ||
|
|
||
| private int _failedUnlockAttempts; | ||
| private TextView _textFailedAttempts; |
| char[] password = EditTextHelper.getEditTextChars(_textPassword); | ||
|
|
||
| if (password.length == 0) { | ||
| Toast.makeText(AuthActivity.this, getString(R.string.error_empty_password), Toast.LENGTH_SHORT).show(); return; |
Comment on lines
+476
to
+483
| long minutes = totalSeconds / 60; | ||
| long seconds = totalSeconds % 60; | ||
|
|
||
| @SuppressLint("DefaultLocale") String timeFormatted = String.format("%02d:%02d", minutes, seconds); | ||
|
|
||
| _textLockout.setText( | ||
| getString(R.string.lockout_message, _failedUnlockAttempts, timeFormatted) | ||
| ); |
Comment on lines
+568
to
+589
| dialog.setOnShowListener(d -> { | ||
| Button positiveButton = dialog.getButton(androidx.appcompat.app.AlertDialog.BUTTON_POSITIVE); | ||
| positiveButton.setEnabled(false); | ||
|
|
||
| new CountDownTimer(delayMillis, 1000) { | ||
| @Override | ||
| public void onTick(long millisUntilFinished) { | ||
| long secondsLeft = (millisUntilFinished + 999) / 1000; | ||
| positiveButton.setText(getString(R.string.ok_with_timer, secondsLeft)); | ||
| } | ||
|
|
||
| @Override | ||
| public void onFinish() { | ||
| positiveButton.setText(getString(android.R.string.ok)); | ||
| positiveButton.setEnabled(true); | ||
| positiveButton.setOnClickListener(v -> { | ||
| dialog.dismiss(); | ||
| selectPassword(); | ||
| }); | ||
| } | ||
| }.start(); | ||
| }); |
| NumberPicker numberPicker = view.findViewById(R.id.numberPicker); | ||
| numberPicker.setMinValue(1); | ||
| numberPicker.setMaxValue(100); | ||
| numberPicker.setValue(currentValue); |
Comment on lines
+488
to
+494
| public int getMaxFailedAttemptsBeforeWipe() { | ||
| return _prefs.getInt("pref_max_failed_attempts", 10); | ||
| } | ||
|
|
||
| public void setMaxFailedAttemptsBeforeWipe(int attempts) { | ||
| _prefs.edit().putInt("pref_max_failed_attempts", attempts).apply(); | ||
| } |
| }); | ||
|
|
||
| _dataWipingPreference = requirePreference("pref_enable_data_wiping"); | ||
| _maxFailedAttemptsPreference = requirePreference("pref_max_failed_attempts"); |
| android:layout_width="wrap_content" | ||
| android:layout_height="wrap_content" | ||
| android:text="" | ||
| android:textColor="@android:color/holo_red_dark" |
Comment on lines
+1
to
+3
| <vector xmlns:android="http://schemas.android.com/apk/res/android" android:height="24dp" android:tint="#000000" android:viewportHeight="24" android:viewportWidth="24" android:width="24dp"> | ||
|
|
||
| <path android:fillColor="@android:color/white" android:pathData="M12,5.99L19.53,19H4.47L12,5.99M12,2L1,21h22L12,2L12,2z"/> |
| <string name="pref_enable_data_wiping_title">Enable data wiping</string> | ||
| <string name="pref_enable_data_wiping_summary">Erase vault data after several successive failed login attempts</string> | ||
| <string name="pref_max_failed_attempts_title">Maximum failed login attempts</string> | ||
| <string name="pref_max_failed_attempts_summary">%1$d attempts</string> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR implements the optional failed-attempt protection proposed in #1749.
It adds a Security setting that allows users to enable automatic vault wiping after a configurable number of failed unlock attempts. The feature is disabled by default. Failed attempts are persisted locally, and after several consecutive failures the authentication screen applies a progressive temporary lockout with a visible countdown.
When data wiping is enabled and the configured limit is reached, the implementation reuses the existing vault deletion functionality to remove the vault file, lock the vault, and exit the app. One attempt before the limit, the user is shown a warning dialog explaining that another failed attempt will erase the vault data.
Fixes #1749
Please let me know if anything needs to be changed in this PR.