Allow customization of password reminder frequency

Close #769
This commit is contained in:
Alexander Bakker 2022-02-17 17:46:48 +01:00
parent 5ce21a94ea
commit 0f3e5c537c
36 changed files with 189 additions and 54 deletions

View file

@ -0,0 +1,56 @@
package com.beemdevelopment.aegis;
import androidx.annotation.StringRes;
import java.util.concurrent.TimeUnit;
public enum PassReminderFreq {
NEVER,
WEEKLY,
BIWEEKLY,
MONTHLY,
QUARTERLY;
public long getDurationMillis() {
long weeks;
switch (this) {
case WEEKLY:
weeks = 1;
break;
case BIWEEKLY:
weeks = 2;
break;
case MONTHLY:
weeks = 4;
break;
case QUARTERLY:
weeks = 13;
break;
default:
weeks = 0;
break;
}
return TimeUnit.MILLISECONDS.convert(weeks * 7L, TimeUnit.DAYS);
}
@StringRes
public int getStringRes() {
switch (this) {
case WEEKLY:
return R.string.password_reminder_freq_weekly;
case BIWEEKLY:
return R.string.password_reminder_freq_biweekly;
case MONTHLY:
return R.string.password_reminder_freq_monthly;
case QUARTERLY:
return R.string.password_reminder_freq_quarterly;
default:
return R.string.password_reminder_freq_never;
}
}
public static PassReminderFreq fromInteger(int i) {
return PassReminderFreq.values()[i];
}
}

View file

@ -19,7 +19,6 @@ import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class Preferences {
public static final int AUTO_LOCK_OFF = 1 << 0;
@ -70,22 +69,44 @@ public class Preferences {
return _prefs.getBoolean("pref_secure_screen", !BuildConfig.DEBUG);
}
public boolean isPasswordReminderEnabled() {
return _prefs.getBoolean("pref_password_reminder", true);
public PassReminderFreq getPasswordReminderFrequency() {
final String key = "pref_password_reminder_freq";
if (_prefs.contains(key) || _prefs.getBoolean("pref_password_reminder", true)) {
int i = _prefs.getInt(key, PassReminderFreq.BIWEEKLY.ordinal());
return PassReminderFreq.fromInteger(i);
}
return PassReminderFreq.NEVER;
}
public void setPasswordReminderFrequency(PassReminderFreq freq) {
_prefs.edit().putInt("pref_password_reminder_freq", freq.ordinal()).apply();
}
public boolean isPasswordReminderNeeded() {
long diff = new Date().getTime() - getPasswordReminderTimestamp().getTime();
long days = TimeUnit.DAYS.convert(diff, TimeUnit.MILLISECONDS);
return isPasswordReminderEnabled() && days >= 30;
return isPasswordReminderNeeded(new Date().getTime());
}
boolean isPasswordReminderNeeded(long currTime) {
PassReminderFreq freq = getPasswordReminderFrequency();
if (freq == PassReminderFreq.NEVER) {
return false;
}
long duration = currTime - getPasswordReminderTimestamp().getTime();
return duration >= freq.getDurationMillis();
}
public Date getPasswordReminderTimestamp() {
return new Date(_prefs.getLong("pref_password_reminder_counter", 0));
}
void setPasswordReminderTimestamp(long timestamp) {
_prefs.edit().putLong("pref_password_reminder_counter", timestamp).apply();
}
public void resetPasswordReminderTimestamp() {
_prefs.edit().putLong("pref_password_reminder_counter", new Date().getTime()).apply();
setPasswordReminderTimestamp(new Date().getTime());
}
public boolean isAccountNameVisible() {
@ -325,4 +346,5 @@ public class Preferences {
return Collections.emptyList();
}
}
}

View file

@ -1,10 +0,0 @@
package com.beemdevelopment.aegis.crypto.pins;
import info.guardianproject.trustedintents.ApkSignaturePin;
public class DebugSignaturePin extends ApkSignaturePin {
public DebugSignaturePin(byte[] cert) {
certificates = new byte[][] { cert };
fingerprints = new String[] { getSHA256Fingerprint() };
}
}

View file

@ -1,5 +1,7 @@
package com.beemdevelopment.aegis.ui.fragments;
import static android.text.TextUtils.isDigitsOnly;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
@ -14,6 +16,7 @@ import androidx.preference.Preference;
import androidx.preference.SwitchPreferenceCompat;
import com.beemdevelopment.aegis.BuildConfig;
import com.beemdevelopment.aegis.PassReminderFreq;
import com.beemdevelopment.aegis.Preferences;
import com.beemdevelopment.aegis.R;
import com.beemdevelopment.aegis.crypto.KeyStoreHandle;
@ -21,8 +24,8 @@ import com.beemdevelopment.aegis.crypto.KeyStoreHandleException;
import com.beemdevelopment.aegis.helpers.BiometricSlotInitializer;
import com.beemdevelopment.aegis.helpers.BiometricsHelper;
import com.beemdevelopment.aegis.services.NotificationService;
import com.beemdevelopment.aegis.ui.dialogs.Dialogs;
import com.beemdevelopment.aegis.ui.SlotManagerActivity;
import com.beemdevelopment.aegis.ui.dialogs.Dialogs;
import com.beemdevelopment.aegis.ui.preferences.SwitchPreference;
import com.beemdevelopment.aegis.ui.tasks.PasswordSlotDecryptTask;
import com.beemdevelopment.aegis.vault.VaultFileCredentials;
@ -33,12 +36,11 @@ import com.beemdevelopment.aegis.vault.slots.Slot;
import com.beemdevelopment.aegis.vault.slots.SlotException;
import com.beemdevelopment.aegis.vault.slots.SlotList;
import java.util.Arrays;
import java.util.List;
import javax.crypto.Cipher;
import static android.text.TextUtils.isDigitsOnly;
public class SecurityPreferencesFragment extends PreferencesFragment {
private SwitchPreference _encryptionPreference;
private SwitchPreference _biometricsPreference;
@ -231,7 +233,28 @@ public class SecurityPreferencesFragment extends PreferencesFragment {
return false;
});
_passwordReminderPreference = findPreference("pref_password_reminder");
_passwordReminderPreference = findPreference("pref_password_reminder_freq");
_passwordReminderPreference.setSummary(getPasswordReminderSummary());
_passwordReminderPreference.setOnPreferenceClickListener((preference) -> {
final PassReminderFreq currFreq = getPreferences().getPasswordReminderFrequency();
final PassReminderFreq[] items = PassReminderFreq.values();
final String[] textItems = Arrays.stream(items)
.map(f -> getString(f.getStringRes()))
.toArray(String[]::new);
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity())
.setTitle(R.string.pref_password_reminder_title)
.setSingleChoiceItems(textItems, currFreq.ordinal(), (dialog, which) -> {
int i = ((AlertDialog) dialog).getListView().getCheckedItemPosition();
PassReminderFreq freq = PassReminderFreq.fromInteger(i);
getPreferences().setPasswordReminderFrequency(freq);
_passwordReminderPreference.setSummary(getPasswordReminderSummary());
dialog.dismiss();
})
.setNegativeButton(android.R.string.cancel, null);
Dialogs.showSecureDialog(builder.create());
return false;
});
}
@Override
@ -281,6 +304,16 @@ public class SecurityPreferencesFragment extends PreferencesFragment {
}
}
private String getPasswordReminderSummary() {
PassReminderFreq freq = getPreferences().getPasswordReminderFrequency();
if (freq == PassReminderFreq.NEVER) {
return getString(R.string.pref_password_reminder_summary_disabled);
}
String freqString = getString(freq.getStringRes()).toLowerCase();
return getString(R.string.pref_password_reminder_summary, freqString);
}
private String getAutoLockSummary() {
final int[] settings = Preferences.AUTO_LOCK_SETTINGS;
final String[] descriptions = getResources().getStringArray(R.array.pref_auto_lock_types);