mirror of
https://github.com/beemdevelopment/Aegis.git
synced 2025-05-16 15:02:54 +00:00
Replace the FAB with a FAB menu and allow manually entering OTP details
This commit is contained in:
parent
3a396fe3f6
commit
44139de212
11 changed files with 152 additions and 51 deletions
|
@ -40,52 +40,64 @@ public class EditProfileActivity extends AegisActivity {
|
|||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_edit_profile);
|
||||
|
||||
_profile = (KeyProfile) getIntent().getSerializableExtra("KeyProfile");
|
||||
|
||||
ActionBar bar = getSupportActionBar();
|
||||
bar.setHomeAsUpIndicator(R.drawable.ic_close);
|
||||
bar.setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
// if the intent doesn't contain a KeyProfile, create a new oneZ
|
||||
_profile = (KeyProfile) getIntent().getSerializableExtra("KeyProfile");
|
||||
if (_profile == null) {
|
||||
_profile = new KeyProfile();
|
||||
setTitle("Add profile");
|
||||
}
|
||||
|
||||
_textName = findViewById(R.id.text_name);
|
||||
_textIssuer = findViewById(R.id.text_issuer);
|
||||
_textPeriod = findViewById(R.id.text_period);
|
||||
_textSecret = findViewById(R.id.text_secret);
|
||||
_spinnerType = findViewById(R.id.spinner_type);
|
||||
SpinnerHelper.fillSpinner(this, _spinnerType, R.array.otp_types_array);
|
||||
_spinnerAlgo = findViewById(R.id.spinner_algo);
|
||||
SpinnerHelper.fillSpinner(this, _spinnerAlgo, R.array.otp_algo_array);
|
||||
_spinnerDigits = findViewById(R.id.spinner_digits);
|
||||
SpinnerHelper.fillSpinner(this, _spinnerDigits, R.array.otp_digits_array);
|
||||
|
||||
updateFields();
|
||||
|
||||
_textName.addTextChangedListener(_textListener);
|
||||
_textIssuer.addTextChangedListener(_textListener);
|
||||
_textPeriod.addTextChangedListener(_textListener);
|
||||
_textSecret.addTextChangedListener(_textListener);
|
||||
_spinnerType.setOnTouchListener(_selectedListener);
|
||||
_spinnerType.setOnItemSelectedListener(_selectedListener);
|
||||
_spinnerAlgo.setOnTouchListener(_selectedListener);
|
||||
_spinnerAlgo.setOnItemSelectedListener(_selectedListener);
|
||||
_spinnerDigits.setOnTouchListener(_selectedListener);
|
||||
_spinnerDigits.setOnItemSelectedListener(_selectedListener);
|
||||
}
|
||||
|
||||
private void updateFields() {
|
||||
DatabaseEntry entry = _profile.getEntry();
|
||||
ImageView imageView = findViewById(R.id.profile_drawable);
|
||||
imageView.setImageDrawable(_profile.getDrawable());
|
||||
|
||||
DatabaseEntry entry = _profile.getEntry();
|
||||
_textName = findViewById(R.id.text_name);
|
||||
_textName.setText(entry.getName());
|
||||
_textName.addTextChangedListener(watcher);
|
||||
|
||||
_textIssuer = findViewById(R.id.text_issuer);
|
||||
_textIssuer.setText(entry.getInfo().getIssuer());
|
||||
_textIssuer.addTextChangedListener(watcher);
|
||||
|
||||
_textPeriod = findViewById(R.id.text_period);
|
||||
_textPeriod.setText(Integer.toString(entry.getInfo().getPeriod()));
|
||||
_textPeriod.addTextChangedListener(watcher);
|
||||
|
||||
_textSecret = findViewById(R.id.text_secret);
|
||||
_textSecret.setText(Base32.encodeOriginal(entry.getInfo().getSecret()));
|
||||
_textSecret.addTextChangedListener(watcher);
|
||||
byte[] secretBytes = entry.getInfo().getSecret();
|
||||
if (secretBytes != null) {
|
||||
_textSecret.setText(Base32.encodeOriginal(secretBytes));
|
||||
}
|
||||
|
||||
String type = entry.getInfo().getType();
|
||||
_spinnerType = findViewById(R.id.spinner_type);
|
||||
SpinnerHelper.fillSpinner(this, _spinnerType, R.array.otp_types_array);
|
||||
_spinnerType.setSelection(getStringResourceIndex(R.array.otp_types_array, type), false);
|
||||
_spinnerType.setOnTouchListener(_selectedListener);
|
||||
_spinnerType.setOnItemSelectedListener(_selectedListener);
|
||||
|
||||
String algo = entry.getInfo().getAlgorithm(false);
|
||||
_spinnerAlgo = findViewById(R.id.spinner_algo);
|
||||
SpinnerHelper.fillSpinner(this, _spinnerAlgo, R.array.otp_algo_array);
|
||||
_spinnerAlgo.setSelection(getStringResourceIndex(R.array.otp_algo_array, algo), false);
|
||||
_spinnerAlgo.setOnTouchListener(_selectedListener);
|
||||
_spinnerAlgo.setOnItemSelectedListener(_selectedListener);
|
||||
|
||||
String digits = Integer.toString(entry.getInfo().getDigits());
|
||||
_spinnerDigits = findViewById(R.id.spinner_digits);
|
||||
SpinnerHelper.fillSpinner(this, _spinnerDigits, R.array.otp_digits_array);
|
||||
_spinnerDigits.setSelection(getStringResourceIndex(R.array.otp_digits_array, digits), false);
|
||||
_spinnerDigits.setOnTouchListener(_selectedListener);
|
||||
_spinnerDigits.setOnItemSelectedListener(_selectedListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -185,7 +197,7 @@ public class EditProfileActivity extends AegisActivity {
|
|||
_edited = true;
|
||||
}
|
||||
|
||||
private TextWatcher watcher = new TextWatcher() {
|
||||
private TextWatcher _textListener = new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
onFieldEdited();
|
||||
|
|
|
@ -13,6 +13,10 @@ public class KeyProfile implements Serializable {
|
|||
private String _code;
|
||||
private DatabaseEntry _entry;
|
||||
|
||||
public KeyProfile() {
|
||||
this(new DatabaseEntry());
|
||||
}
|
||||
|
||||
public KeyProfile(DatabaseEntry entry) {
|
||||
_entry = entry;
|
||||
}
|
||||
|
@ -35,7 +39,7 @@ public class KeyProfile implements Serializable {
|
|||
|
||||
public TextDrawable getDrawable() {
|
||||
String name = _entry.getName();
|
||||
if (name == null) {
|
||||
if (name == null || name.length() <= 1) {
|
||||
return null;
|
||||
}
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@ import android.content.DialogInterface;
|
|||
import android.content.Intent;
|
||||
import android.media.MediaScannerConnection;
|
||||
import android.support.design.widget.BottomSheetDialog;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
|
@ -18,6 +17,9 @@ import android.view.View;
|
|||
import android.widget.LinearLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.getbase.floatingactionbutton.FloatingActionButton;
|
||||
import com.getbase.floatingactionbutton.FloatingActionsMenu;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.UndeclaredThrowableException;
|
||||
|
@ -32,13 +34,14 @@ import me.impy.aegis.util.ByteInputStream;
|
|||
|
||||
public class MainActivity extends AegisActivity implements KeyProfileView.Listener {
|
||||
// activity request codes
|
||||
private static final int CODE_GET_KEYINFO = 0;
|
||||
private static final int CODE_SCAN_KEYINFO = 0;
|
||||
private static final int CODE_ADD_KEYINFO = 1;
|
||||
private static final int CODE_EDIT_KEYINFO = 2;
|
||||
private static final int CODE_DO_INTRO = 3;
|
||||
private static final int CODE_DECRYPT = 4;
|
||||
private static final int CODE_IMPORT = 5;
|
||||
private static final int CODE_PREFERENCES = 6;
|
||||
private static final int CODE_ENTER_KEYINFO = 3;
|
||||
private static final int CODE_DO_INTRO = 4;
|
||||
private static final int CODE_DECRYPT = 5;
|
||||
private static final int CODE_IMPORT = 6;
|
||||
private static final int CODE_PREFERENCES = 7;
|
||||
|
||||
// permission request codes
|
||||
private static final int CODE_PERM_EXPORT = 0;
|
||||
|
@ -60,8 +63,7 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
|
|||
|
||||
// set up the main view
|
||||
setContentView(R.layout.activity_main);
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
setSupportActionBar(findViewById(R.id.toolbar));
|
||||
|
||||
// set up the key profile view
|
||||
_keyProfileView = (KeyProfileView) getSupportFragmentManager().findFragmentById(R.id.key_profiles);
|
||||
|
@ -69,9 +71,15 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
|
|||
_keyProfileView.setShowIssuer(_app.getPreferences().getBoolean("pref_issuer", false));
|
||||
|
||||
// set up the floating action button
|
||||
FloatingActionButton fab = findViewById(R.id.fab);
|
||||
fab.setEnabled(true);
|
||||
fab.setOnClickListener(view -> onGetKeyInfo());
|
||||
FloatingActionsMenu fabMenu = findViewById(R.id.fab);
|
||||
findViewById(R.id.fab_enter).setOnClickListener(view -> {
|
||||
fabMenu.collapse();
|
||||
onEnterKeyInfo();
|
||||
});
|
||||
findViewById(R.id.fab_scan).setOnClickListener(view -> {
|
||||
fabMenu.collapse();
|
||||
onScanKeyInfo();
|
||||
});
|
||||
|
||||
// skip this part if this is the not initial startup and the database has been unlocked
|
||||
if (!_app.isRunning() && _db.isLocked()) {
|
||||
|
@ -133,8 +141,8 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
|
|||
}
|
||||
|
||||
switch (requestCode) {
|
||||
case CODE_GET_KEYINFO:
|
||||
onGetKeyInfoResult(resultCode, data);
|
||||
case CODE_SCAN_KEYINFO:
|
||||
onScanKeyInfoResult(resultCode, data);
|
||||
break;
|
||||
case CODE_ADD_KEYINFO:
|
||||
onAddKeyInfoResult(resultCode, data);
|
||||
|
@ -142,6 +150,9 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
|
|||
case CODE_EDIT_KEYINFO:
|
||||
onEditKeyInfoResult(resultCode, data);
|
||||
break;
|
||||
case CODE_ENTER_KEYINFO:
|
||||
onEnterKeyInfoResult(resultCode, data);
|
||||
break;
|
||||
case CODE_DO_INTRO:
|
||||
onDoIntroResult(resultCode, data);
|
||||
break;
|
||||
|
@ -172,7 +183,7 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
|
|||
onImport();
|
||||
break;
|
||||
case CODE_PERM_CAMERA:
|
||||
onGetKeyInfo();
|
||||
onScanKeyInfo();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -297,7 +308,12 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
|
|||
saveDatabase();
|
||||
}
|
||||
|
||||
private void onGetKeyInfo() {
|
||||
private void onEnterKeyInfo() {
|
||||
Intent intent = new Intent(this, EditProfileActivity.class);
|
||||
startActivityForResult(intent, CODE_ENTER_KEYINFO);
|
||||
}
|
||||
|
||||
private void onScanKeyInfo() {
|
||||
if (!PermissionHelper.request(this, CODE_PERM_CAMERA, Manifest.permission.CAMERA)) {
|
||||
return;
|
||||
}
|
||||
|
@ -305,7 +321,7 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
|
|||
startScanActivity();
|
||||
}
|
||||
|
||||
private void onGetKeyInfoResult(int resultCode, Intent data) {
|
||||
private void onScanKeyInfoResult(int resultCode, Intent data) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
KeyProfile keyProfile = (KeyProfile)data.getSerializableExtra("KeyProfile");
|
||||
Intent intent = new Intent(this, AddProfileActivity.class);
|
||||
|
@ -339,6 +355,21 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
|
|||
}
|
||||
}
|
||||
|
||||
private void onEnterKeyInfoResult(int resultCode, Intent data) {
|
||||
if (resultCode == RESULT_OK) {
|
||||
KeyProfile profile = (KeyProfile) data.getSerializableExtra("KeyProfile");
|
||||
try {
|
||||
addKey(profile);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Toast.makeText(this, "An error occurred while trying to add an entry", Toast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
_keyProfileView.addKey(profile);
|
||||
saveDatabase();
|
||||
}
|
||||
}
|
||||
|
||||
private void addKey(KeyProfile profile) {
|
||||
profile.refreshCode();
|
||||
|
||||
|
@ -395,7 +426,7 @@ public class MainActivity extends AegisActivity implements KeyProfileView.Listen
|
|||
|
||||
private void startScanActivity() {
|
||||
Intent scannerActivity = new Intent(getApplicationContext(), ScannerActivity.class);
|
||||
startActivityForResult(scannerActivity, CODE_GET_KEYINFO);
|
||||
startActivityForResult(scannerActivity, CODE_SCAN_KEYINFO);
|
||||
}
|
||||
|
||||
private boolean doShortcutActions() {
|
||||
|
|
|
@ -7,11 +7,11 @@ import java.io.Serializable;
|
|||
import me.impy.aegis.encoding.Base32;
|
||||
|
||||
public class KeyInfo implements Serializable {
|
||||
private String _type;
|
||||
private String _type = "totp";
|
||||
private byte[] _secret;
|
||||
private String _accountName;
|
||||
private String _issuer;
|
||||
private long _counter;
|
||||
private String _accountName = "";
|
||||
private String _issuer = "";
|
||||
private long _counter = 0;
|
||||
private String _algorithm = "SHA1";
|
||||
private int _digits = 6;
|
||||
private int _period = 30;
|
||||
|
|
|
@ -13,6 +13,10 @@ public class DatabaseEntry implements Serializable {
|
|||
private String _icon = "";
|
||||
private KeyInfo _info;
|
||||
|
||||
public DatabaseEntry() {
|
||||
this(new KeyInfo());
|
||||
}
|
||||
|
||||
public DatabaseEntry(KeyInfo info) {
|
||||
_info = info;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue