diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml deleted file mode 100644 index bc1ce66..0000000 --- a/.idea/deploymentTargetDropDown.xml +++ /dev/null @@ -1,17 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b8ea110..050de76 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -33,10 +33,10 @@ android:name=".MainActivity" android:exported="true" android:label="@string/app_name" - android:theme="@style/Theme.CringeAuthenticator"> + android:theme="@style/Theme.CringeAuthenticator.None"> + android:theme="@style/Theme.CringeAuthenticator.None"> diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/MainActivity.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/MainActivity.java index 3564f39..1e83e03 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/MainActivity.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/MainActivity.java @@ -52,6 +52,9 @@ public class MainActivity extends AppCompatActivity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); + // TODO: load configured theme + setTheme(R.style.Theme_CringeAuthenticator_Blue_Green); + Executor executor = ContextCompat.getMainExecutor(this); BiometricPrompt prompt = new BiometricPrompt(this, executor, new BiometricPrompt.AuthenticationCallback() { @Override @@ -140,7 +143,6 @@ public class MainActivity extends AppCompatActivity { @Override public void onBackPressed() { - Log.i("AMOGUS", "navigateUp"); if(!(NavigationUtil.getCurrentFragment(this) instanceof HomeFragment)) { NavigationUtil.navigate(this, HomeFragment.class, null); } @@ -184,7 +186,7 @@ public class MainActivity extends AppCompatActivity { showHOTPDialog(); break; } - showTOTPDialog(); + dialog.dismiss(); }); @@ -197,6 +199,27 @@ public class MainActivity extends AppCompatActivity { binding.inputDigits.setAdapter(new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, new Integer[]{6, 7, 8, 9, 10, 11, 12})); showCodeDialog(binding.getRoot(), () -> { // TODO: handle input + Fragment fragment = NavigationUtil.getCurrentFragment(this); + if(!(fragment instanceof DynamicFragment)) return; + + try { + String name = binding.inputName.getText().toString(); + String secret = binding.inputSecret.getText().toString(); + OTPAlgorithm algorithm = (OTPAlgorithm) binding.inputAlgorithm.getSelectedItem(); + int digits = (int) binding.inputDigits.getSelectedItem(); + int period = Integer.parseInt(binding.inputPeriod.getText().toString()); + + OTPData data = new OTPData(name, OTPType.TOTP, secret, algorithm, digits, period, 0); + if(!data.validate()) { + // TODO: error + return; + } + + ((DynamicFragment) fragment).addOTP(data); + }catch(NumberFormatException e) { + // TODO: error + return; + } }); } diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/OTPData.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/OTPData.java index 7f5f353..16a57c7 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/OTPData.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/OTPData.java @@ -4,6 +4,7 @@ import androidx.annotation.NonNull; import com.cringe_studios.cringe_authenticator_library.OTP; import com.cringe_studios.cringe_authenticator_library.OTPAlgorithm; +import com.cringe_studios.cringe_authenticator_library.OTPException; import com.cringe_studios.cringe_authenticator_library.OTPType; import java.io.Serializable; @@ -17,12 +18,12 @@ public class OTPData implements Serializable { private OTPAlgorithm algorithm; private int digits; private int period; - private int counter; + private long counter; // Cached - private OTP otp; + private transient OTP otp; - public OTPData(String name, OTPType type, String secret, OTPAlgorithm algorithm, int digits, int period, int counter) { + public OTPData(String name, OTPType type, String secret, OTPAlgorithm algorithm, int digits, int period, long counter) { this.name = name; this.type = type; this.secret = secret; @@ -56,11 +57,29 @@ public class OTPData implements Serializable { return period; } - public int getCounter() { + public long getCounter() { return counter; } - public OTP toOTP() { + public String getPin() { + return getOTP().getPin(); + } + + public void incrementCounter() { + getOTP().incrementCounter(); + this.counter = getOTP().getCounter(); + } + + public boolean validate() { + try { + getOTP(); + return true; + }catch(IllegalArgumentException | OTPException e) { + return false; + } + } + + private OTP getOTP() { // TODO: checksum if(otp != null) return otp; return otp = OTP.createNewOTP(type, secret, algorithm, digits, counter, period, false); diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/DynamicFragment.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/DynamicFragment.java index 7923dc4..be2fdbc 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/DynamicFragment.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/DynamicFragment.java @@ -60,7 +60,7 @@ public class DynamicFragment extends Fragment { for(int i = 0; i < binding.itemList.getChildCount(); i++) { OTPListItem vh = (OTPListItem) binding.itemList.findViewHolderForAdapterPosition(i); if(vh == null) continue; - vh.getBinding().otpCode.setText(vh.getOTPData().toOTP().getPin()); + vh.getBinding().otpCode.setText(vh.getOTPData().getPin()); } handler.postDelayed(refreshCodes, 1000L); diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/MenuFragment.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/MenuFragment.java index acda8ee..65a34af 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/MenuFragment.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/fragment/MenuFragment.java @@ -31,7 +31,7 @@ public class MenuFragment extends Fragment { String[] items = {"a", "b"}; for(String item : items) { - MenuItemBinding itemBinding = MenuItemBinding.inflate(inflater); + MenuItemBinding itemBinding = MenuItemBinding.inflate(inflater, binding.menuItems, false); itemBinding.button.setText(item); itemBinding.button.setOnClickListener(view -> { Bundle bundle = new Bundle(); diff --git a/app/src/main/java/com/cringe_studios/cringe_authenticator/otplist/OTPListAdapter.java b/app/src/main/java/com/cringe_studios/cringe_authenticator/otplist/OTPListAdapter.java index 91c0490..ee769a0 100644 --- a/app/src/main/java/com/cringe_studios/cringe_authenticator/otplist/OTPListAdapter.java +++ b/app/src/main/java/com/cringe_studios/cringe_authenticator/otplist/OTPListAdapter.java @@ -1,14 +1,18 @@ package com.cringe_studios.cringe_authenticator.otplist; import android.content.Context; +import android.os.Handler; +import android.os.Looper; import android.view.LayoutInflater; import android.view.ViewGroup; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.recyclerview.widget.RecyclerView; import com.cringe_studios.cringe_authenticator.OTPData; import com.cringe_studios.cringe_authenticator.databinding.OtpCodeBinding; +import com.cringe_studios.cringe_authenticator_library.OTPType; import java.util.ArrayList; import java.util.List; @@ -19,9 +23,12 @@ public class OTPListAdapter extends RecyclerView.Adapter { private List items; + private Handler handler; + public OTPListAdapter(Context context) { this.inflater = LayoutInflater.from(context); this.items = new ArrayList<>(); + this.handler = new Handler(Looper.getMainLooper()); } @NonNull @@ -33,8 +40,20 @@ public class OTPListAdapter extends RecyclerView.Adapter { @Override public void onBindViewHolder(@NonNull OTPListItem holder, int position) { - holder.setOTPData(items.get(position)); + OTPData data = items.get(position); + + holder.setOTPData(data); holder.getBinding().label.setText(holder.getOTPData().getName()); + + holder.getBinding().getRoot().setOnClickListener(view -> { + if(data.getType() != OTPType.HOTP) return; + + // Click delay for HOTP + view.setClickable(false); + Toast.makeText(view.getContext(), "Generated new code", Toast.LENGTH_LONG).show(); + data.incrementCounter(); + handler.postDelayed(() -> view.setClickable(true), 5000); + }); } @Override diff --git a/app/src/main/res/drawable/button_theme_orange_turquoise.xml b/app/src/main/res/drawable/button_theme_orange_turquoise.xml deleted file mode 100644 index 43ee0f9..0000000 --- a/app/src/main/res/drawable/button_theme_orange_turquoise.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_theme_pink_green.xml b/app/src/main/res/drawable/button_theme_pink_green.xml deleted file mode 100644 index e06a61e..0000000 --- a/app/src/main/res/drawable/button_theme_pink_green.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/drawable/button_theme_red_blue.xml b/app/src/main/res/drawable/button_theme_red_blue.xml deleted file mode 100644 index 1c0bd56..0000000 --- a/app/src/main/res/drawable/button_theme_red_blue.xml +++ /dev/null @@ -1,39 +0,0 @@ - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/app/src/main/res/layout/menu_item.xml b/app/src/main/res/layout/menu_item.xml index 920fad1..a8f5d5c 100644 --- a/app/src/main/res/layout/menu_item.xml +++ b/app/src/main/res/layout/menu_item.xml @@ -1,13 +1,16 @@ + android:layout_height="wrap_content" + android:orientation="vertical" + android:layout_margin="5dp" + android:background="@drawable/button_themed" > -