From d04bf9d09ab1be4e84079a8cd07fb4e460f3a25b Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Fri, 1 Nov 2024 13:41:10 +0530 Subject: [PATCH 01/20] feat: add a password manager activity to group password managing operation --- app/src/main/AndroidManifest.xml | 1 + .../com/passwordmanager/ui/MainActivity.java | 15 +-- .../ui/PasswordManagerActivity.java | 44 +++++++ app/src/main/res/layout/activity_main.xml | 119 +++++++++--------- .../res/layout/activity_password_manager.xml | 33 +++++ app/src/main/res/values/strings.xml | 2 + 6 files changed, 141 insertions(+), 73 deletions(-) create mode 100644 app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java create mode 100644 app/src/main/res/layout/activity_password_manager.xml diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 4bc04022..00a5c1bb 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -34,6 +34,7 @@ + diff --git a/app/src/main/java/com/passwordmanager/ui/MainActivity.java b/app/src/main/java/com/passwordmanager/ui/MainActivity.java index cfd6e1e2..4a7dbf47 100644 --- a/app/src/main/java/com/passwordmanager/ui/MainActivity.java +++ b/app/src/main/java/com/passwordmanager/ui/MainActivity.java @@ -52,18 +52,13 @@ public void onRequestPermissionsResult( // Added all the onclick event listiners private void addOnClickListenerOnButton(ActivityMainBinding binding) { - binding.savePasswordBtn.setOnClickListener(v -> { - Intent savepasswordintent = new Intent(MainActivity.this, SavePasswordActivity.class); - startActivity(savepasswordintent); + binding.passwordManagerBtn.setOnClickListener(v -> { + Intent passwordmanagerintent = new Intent(MainActivity.this, PasswordManagerActivity.class); + startActivity(passwordmanagerintent); }); - binding.loadPasswordBtn.setOnClickListener(v -> { - Intent loadpasswordintent = new Intent(MainActivity.this, LoadPasswordActivity.class); - startActivity(loadpasswordintent); - }); - - binding.aboutUsBtn.setOnClickListener(v -> { - Intent aboutusintent = new Intent(MainActivity.this, AboutUsActivity.class); + binding.aboutUsBtn.setOnClickListener(v -> { + Intent aboutusintent = new Intent(MainActivity.this, AboutUsActivity.class); startActivity(aboutusintent); }); diff --git a/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java b/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java new file mode 100644 index 00000000..04e4e4b1 --- /dev/null +++ b/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java @@ -0,0 +1,44 @@ +package com.passwordmanager.ui; + +import android.os.Bundle; +import android.content.Intent; +import androidx.appcompat.app.AppCompatActivity; +import androidx.core.view.WindowCompat; +import android.view.LayoutInflater; + +import com.passwordmanager.R; +import com.passwordmanager.databinding.ActivityPasswordManagerBinding; +// import com.passwordmanager.utils.Permissions; + +public class PasswordManagerActivity extends AppCompatActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + ActivityPasswordManagerBinding binding = ActivityPasswordManagerBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + // Add event onclick listener + // addOnClickListenerOnButton(binding); + + // Make window fullscreen + WindowCompat.setDecorFitsSystemWindows(getWindow(), false); + } + + // Added all the onclick event listiners + private void addOnClickListenerOnButton(ActivityPasswordManagerBinding binding) { + binding.savePasswordBtn.setOnClickListener( + v -> { + Intent savepasswordintent = new Intent(PasswordManager.this, SavePasswordActivity.class); + startActivity(savepasswordintent); + } + ); + + binding.loadPasswordBtn.setOnClickListener( + v -> { + Intent loadpasswordintent = new Intent(PasswordManager.this, LoadPasswordActivity.class); + startActivity(loadpasswordintent); + } + ); + } +} diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index 3768668e..18e09e6f 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -1,70 +1,63 @@ - - - - - - - - - - - + tools:context=".ui.MainActivity" + android:padding="4sp" > + + - - - - - + + + + + + + + + + + + diff --git a/app/src/main/res/layout/activity_password_manager.xml b/app/src/main/res/layout/activity_password_manager.xml new file mode 100644 index 00000000..e2882c03 --- /dev/null +++ b/app/src/main/res/layout/activity_password_manager.xml @@ -0,0 +1,33 @@ + + + + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index ec970ff1..feac910e 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -20,6 +20,7 @@ Username Password Notes + Password Manager Save Password Load Password Update Password @@ -30,6 +31,7 @@ View Changelog + Password Manager Load Password Save Password View Password From 7a039f046eefd778338bb29cb6f0ec826d3929a8 Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Fri, 1 Nov 2024 13:58:01 +0530 Subject: [PATCH 02/20] feat: add some new buttons in password manager activity --- .../ui/PasswordManagerActivity.java | 33 ++++++++++++------- .../res/layout/activity_password_manager.xml | 21 ++++++++++++ app/src/main/res/values/strings.xml | 4 +++ 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java b/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java index 04e4e4b1..00f10155 100644 --- a/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java +++ b/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java @@ -2,6 +2,7 @@ import android.os.Bundle; import android.content.Intent; +import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import androidx.core.view.WindowCompat; import android.view.LayoutInflater; @@ -27,18 +28,26 @@ protected void onCreate(Bundle savedInstanceState) { // Added all the onclick event listiners private void addOnClickListenerOnButton(ActivityPasswordManagerBinding binding) { - binding.savePasswordBtn.setOnClickListener( - v -> { - Intent savepasswordintent = new Intent(PasswordManager.this, SavePasswordActivity.class); - startActivity(savepasswordintent); - } - ); + binding.savePasswordBtn.setOnClickListener(v -> { + Intent savepasswordintent = new Intent(PasswordManager.this, SavePasswordActivity.class); + startActivity(savepasswordintent); + }); - binding.loadPasswordBtn.setOnClickListener( - v -> { - Intent loadpasswordintent = new Intent(PasswordManager.this, LoadPasswordActivity.class); - startActivity(loadpasswordintent); - } - ); + binding.loadPasswordBtn.setOnClickListener(v -> { + Intent loadpasswordintent = new Intent(PasswordManager.this, LoadPasswordActivity.class); + startActivity(loadpasswordintent); + }); + + binding.securityCheckBtn.setOnClickListener(v -> { + Toast.makeText(SavePasswordActivity.this, getString(R.string.future_feat_clause), Toast.LENGTH_SHORT).show(); + }); + + binding.importPasswordBtn.setOnClickListener(v -> { + Toast.makeText(SavePasswordActivity.this, getString(R.string.future_feat_clause), Toast.LENGTH_SHORT).show(); + }); + + binding.exportPasswordBtn.setOnClickListener(v -> { + Toast.makeText(SavePasswordActivity.this, getString(R.string.future_feat_clause), Toast.LENGTH_SHORT).show(); + }); } } diff --git a/app/src/main/res/layout/activity_password_manager.xml b/app/src/main/res/layout/activity_password_manager.xml index e2882c03..e5c1210a 100644 --- a/app/src/main/res/layout/activity_password_manager.xml +++ b/app/src/main/res/layout/activity_password_manager.xml @@ -30,4 +30,25 @@ android:text="@string/load_password_button_text" android:textSize="14dp" /> + + + + + + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index feac910e..1d359288 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -25,6 +25,9 @@ Load Password Update Password Delete Password + Import Password + Export Password + Check Security About Us View License View Security Guidelines @@ -52,6 +55,7 @@ Permission Denied + Feature is under development!! 404: Not Found!! Warning: please fill the form first!! Failed: please try again!! From 30e5b2798755db123f2acefef092856ce5cf8515 Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Sun, 20 Jul 2025 18:58:04 +0530 Subject: [PATCH 03/20] Make a Layout --- .../passwordmanager/ui/PasswordManagerActivity.java | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java b/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java index 00f10155..b6a4161c 100644 --- a/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java +++ b/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java @@ -9,7 +9,6 @@ import com.passwordmanager.R; import com.passwordmanager.databinding.ActivityPasswordManagerBinding; -// import com.passwordmanager.utils.Permissions; public class PasswordManagerActivity extends AppCompatActivity { @@ -20,7 +19,7 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(binding.getRoot()); // Add event onclick listener - // addOnClickListenerOnButton(binding); + addOnClickListenerOnButton(binding); // Make window fullscreen WindowCompat.setDecorFitsSystemWindows(getWindow(), false); @@ -29,25 +28,25 @@ protected void onCreate(Bundle savedInstanceState) { // Added all the onclick event listiners private void addOnClickListenerOnButton(ActivityPasswordManagerBinding binding) { binding.savePasswordBtn.setOnClickListener(v -> { - Intent savepasswordintent = new Intent(PasswordManager.this, SavePasswordActivity.class); + Intent savepasswordintent = new Intent(PasswordManagerActivity.this, SavePasswordActivity.class); startActivity(savepasswordintent); }); binding.loadPasswordBtn.setOnClickListener(v -> { - Intent loadpasswordintent = new Intent(PasswordManager.this, LoadPasswordActivity.class); + Intent loadpasswordintent = new Intent(PasswordManagerActivity.this, LoadPasswordActivity.class); startActivity(loadpasswordintent); }); binding.securityCheckBtn.setOnClickListener(v -> { - Toast.makeText(SavePasswordActivity.this, getString(R.string.future_feat_clause), Toast.LENGTH_SHORT).show(); + Toast.makeText(this, getString(R.string.future_feat_clause), Toast.LENGTH_SHORT).show(); }); binding.importPasswordBtn.setOnClickListener(v -> { - Toast.makeText(SavePasswordActivity.this, getString(R.string.future_feat_clause), Toast.LENGTH_SHORT).show(); + Toast.makeText(this, getString(R.string.future_feat_clause), Toast.LENGTH_SHORT).show(); }); binding.exportPasswordBtn.setOnClickListener(v -> { - Toast.makeText(SavePasswordActivity.this, getString(R.string.future_feat_clause), Toast.LENGTH_SHORT).show(); + Toast.makeText(this, getString(R.string.future_feat_clause), Toast.LENGTH_SHORT).show(); }); } } From 20b3ddce59a7a4cd87abd7ac5873d59338557199 Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Sun, 20 Jul 2025 19:21:39 +0530 Subject: [PATCH 04/20] Make a simple clipboard experiment --- .../ui/PasswordManagerActivity.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java b/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java index b6a4161c..2cff8a3f 100644 --- a/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java +++ b/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java @@ -2,6 +2,9 @@ import android.os.Bundle; import android.content.Intent; +import android.content.Context; +import android.content.ClipData; +import android.content.ClipboardManager; import android.widget.Toast; import androidx.appcompat.app.AppCompatActivity; import androidx.core.view.WindowCompat; @@ -47,6 +50,18 @@ private void addOnClickListenerOnButton(ActivityPasswordManagerBinding binding) binding.exportPasswordBtn.setOnClickListener(v -> { Toast.makeText(this, getString(R.string.future_feat_clause), Toast.LENGTH_SHORT).show(); + + String textToCopy = "Your data is copied to clipboard!!"; + + ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); + ClipData clip = ClipData.newPlainText("Copied Text", textToCopy); + + if (clipboard != null) { + clipboard.setPrimaryClip(clip); + Toast.makeText(this, "Text copied to clipboard!", Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(this, "Clipboard service not available.", Toast.LENGTH_SHORT).show(); + } }); } } From 6905afa4384e0b1f524d5f1f6204bcbcdb0334f3 Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Sun, 20 Jul 2025 20:12:55 +0530 Subject: [PATCH 05/20] Copy to clipboard --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 3 +- .../ui/PasswordManagerActivity.java | 38 ++++++++++++++++++- 3 files changed, 39 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 506ff222..dcfe88a6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -86,4 +86,5 @@ dependencies { implementation 'com.google.android.material:material:1.9.0' implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.databinding:viewbinding:7.4.1' + implementation 'org.json:json:20250517' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 00a5c1bb..2ccb2533 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ + xmlns:tools="http://schemas.android.com/tools"> { Toast.makeText(this, getString(R.string.future_feat_clause), Toast.LENGTH_SHORT).show(); - String textToCopy = "Your data is copied to clipboard!!"; + controller = new Controller(PasswordManagerActivity.this); + List passwordList = controller.getAllPasswords(); + String textToCopy = convertPasswordsToJson(passwordList); + ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); ClipData clip = ClipData.newPlainText("Copied Text", textToCopy); @@ -64,4 +76,28 @@ private void addOnClickListenerOnButton(ActivityPasswordManagerBinding binding) } }); } + + // New method to convert List to JSON string + private String convertPasswordsToJson(List passwordList) { + JSONArray jsonArray = new JSONArray(); + try { + for (PasswordModel password : passwordList) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("id", password.getId()); + jsonObject.put("domain", password.getDomain()); + jsonObject.put("username", password.getUsername()); + jsonObject.put("password", password.getPassword()); // !!! Highly Sensitive Data !!! + jsonObject.put("notes", password.getNotes()); + jsonObject.put("createdAt", password.getCreatedAt()); + jsonObject.put("updatedAt", password.getUpdatedAt()); + jsonArray.put(jsonObject); + } + // Move the return statement INSIDE the try block, + // so it's covered by the catch for JSONException + return jsonArray.toString(4); + } catch (JSONException e) { + e.printStackTrace(); // Log the error for debugging + return null; // Return null or throw a custom exception + } + } } From 106705f4b4fc71e643d4ddcd65796b40bdb820c1 Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Sun, 20 Jul 2025 21:47:36 +0530 Subject: [PATCH 06/20] refactor: comment permission code in manifest --- app/src/main/AndroidManifest.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2ccb2533..c100584f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -6,7 +6,7 @@ android:minSdkVersion="26" android:targetSdkVersion="33" /> - + Date: Sun, 20 Jul 2025 21:51:47 +0530 Subject: [PATCH 07/20] feat: add basic data exporting --- .../ui/PasswordManagerActivity.java | 107 ++++++++++++------ 1 file changed, 71 insertions(+), 36 deletions(-) diff --git a/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java b/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java index 50b4bdc0..cc761464 100644 --- a/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java +++ b/app/src/main/java/com/passwordmanager/ui/PasswordManagerActivity.java @@ -1,11 +1,11 @@ package com.passwordmanager.ui; +import android.net.Uri; import android.os.Bundle; -import android.content.Intent; -import android.content.Context; -import android.content.ClipData; -import android.content.ClipboardManager; +import android.provider.DocumentsContract; import android.widget.Toast; +import androidx.annotation.Nullable; +import android.content.Intent; import androidx.appcompat.app.AppCompatActivity; import androidx.core.view.WindowCompat; import android.view.LayoutInflater; @@ -20,9 +20,13 @@ import com.passwordmanager.databinding.ActivityPasswordManagerBinding; import java.util.List; +import java.io.OutputStream; public class PasswordManagerActivity extends AppCompatActivity { private Controller controller; + private static final int CREATE_EXPORT_DATA_FILE_REQUEST = 1; + + private String exportPasswordsContent; @Override protected void onCreate(Bundle savedInstanceState) { @@ -58,46 +62,77 @@ private void addOnClickListenerOnButton(ActivityPasswordManagerBinding binding) }); binding.exportPasswordBtn.setOnClickListener(v -> { - Toast.makeText(this, getString(R.string.future_feat_clause), Toast.LENGTH_SHORT).show(); - controller = new Controller(PasswordManagerActivity.this); - List passwordList = controller.getAllPasswords(); + List allPasswords = controller.getAllPasswords(); + exportPasswordsContent = convertPasswordsToJson(allPasswords); - String textToCopy = convertPasswordsToJson(passwordList); - - ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE); - ClipData clip = ClipData.newPlainText("Copied Text", textToCopy); - - if (clipboard != null) { - clipboard.setPrimaryClip(clip); - Toast.makeText(this, "Text copied to clipboard!", Toast.LENGTH_SHORT).show(); + if (exportPasswordsContent != null) { + createFile(null); } else { - Toast.makeText(this, "Clipboard service not available.", Toast.LENGTH_SHORT).show(); + Toast.makeText(this, "Failed to generate secure report content.", Toast.LENGTH_SHORT).show(); } }); } + + private String convertPasswordsToJson(List passwordList) { + JSONArray jsonArray = new JSONArray(); + try { + for (PasswordModel password : passwordList) { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("id", password.getId()); + jsonObject.put("domain", password.getDomain()); + jsonObject.put("username", password.getUsername()); + jsonObject.put("password", password.getPassword()); // !!! Highly Sensitive Data !!! + jsonObject.put("notes", password.getNotes()); + jsonObject.put("createdAt", password.getCreatedAt()); + jsonObject.put("updatedAt", password.getUpdatedAt()); + jsonArray.put(jsonObject); + } + + return jsonArray.toString(4); + } catch (JSONException e) { + return null; + } + } + + private void createFile(@Nullable Uri pickerInitialUri) { + Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("application/json"); + intent.putExtra(Intent.EXTRA_TITLE, "password_manager_data.json"); - // New method to convert List to JSON string - private String convertPasswordsToJson(List passwordList) { - JSONArray jsonArray = new JSONArray(); - try { - for (PasswordModel password : passwordList) { - JSONObject jsonObject = new JSONObject(); - jsonObject.put("id", password.getId()); - jsonObject.put("domain", password.getDomain()); - jsonObject.put("username", password.getUsername()); - jsonObject.put("password", password.getPassword()); // !!! Highly Sensitive Data !!! - jsonObject.put("notes", password.getNotes()); - jsonObject.put("createdAt", password.getCreatedAt()); - jsonObject.put("updatedAt", password.getUpdatedAt()); - jsonArray.put(jsonObject); + if (pickerInitialUri != null) { + intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri); + } + + startActivityForResult(intent, CREATE_EXPORT_DATA_FILE_REQUEST); + } + + @Override + protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { + super.onActivityResult(requestCode, resultCode, data); + + if (requestCode == CREATE_EXPORT_DATA_FILE_REQUEST) { + if (resultCode == RESULT_OK && data != null) { + Uri uri = data.getData(); + if (uri != null && exportPasswordsContent != null) { + try { + OutputStream outputStream = getContentResolver().openOutputStream(uri); + if (outputStream != null) { + outputStream.write(exportPasswordsContent.getBytes()); + outputStream.close(); + Toast.makeText(this, "Data export successfully to: " + uri.getPath(), Toast.LENGTH_LONG).show(); + } + } catch (Exception e) { + e.printStackTrace(); + Toast.makeText(this, "Error export data: " + e.getMessage(), Toast.LENGTH_LONG).show(); + } + } else { + Toast.makeText(this, "Failed to get file URI or report content is empty.", Toast.LENGTH_SHORT).show(); } - // Move the return statement INSIDE the try block, - // so it's covered by the catch for JSONException - return jsonArray.toString(4); - } catch (JSONException e) { - e.printStackTrace(); // Log the error for debugging - return null; // Return null or throw a custom exception + } else { + Toast.makeText(this, "File creation cancelled.", Toast.LENGTH_SHORT).show(); } } + } } From 0ef6d46142f49c9ea571490f942ba3d9d3556a51 Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Tue, 22 Jul 2025 20:43:44 +0530 Subject: [PATCH 08/20] chore: delete dependency-check.yml --- .github/workflows/dependency-check.yml | 23 ----------------------- 1 file changed, 23 deletions(-) delete mode 100644 .github/workflows/dependency-check.yml diff --git a/.github/workflows/dependency-check.yml b/.github/workflows/dependency-check.yml deleted file mode 100644 index 0880129c..00000000 --- a/.github/workflows/dependency-check.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Gradle Dependency Submission - -on: - push: - branches: [ 'main' ] - workflow_dispatch: # This makes it a manual trigger - -permissions: - contents: write - -jobs: - dependency-submission: - runs-on: ubuntu-latest - steps: - - name: Checkout sources - uses: actions/checkout@v4 - - name: Setup Java - uses: actions/setup-java@v4 - with: - distribution: 'temurin' - java-version: 17 - - name: Generate and submit dependency graph - uses: gradle/actions/dependency-submission@v4 From e1436a0e8a15408681086a094106d00ee68eb122 Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Tue, 22 Jul 2025 21:26:19 +0530 Subject: [PATCH 09/20] chore: format build.gradle --- app/build.gradle | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index dcfe88a6..6400dbe1 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -35,7 +35,7 @@ android { if (keystorePropertiesFile.exists()) { def keystoreProperties = new Properties() keystoreProperties.load(new FileInputStream(keystorePropertiesFile)) - + keyAlias keystoreProperties['keyAlias'] keyPassword keystoreProperties['keyPassword'] storeFile file(keystoreProperties['storeFile']) @@ -43,7 +43,7 @@ android { } } } - + splits { abi { enable true @@ -69,6 +69,7 @@ android { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } } @@ -76,7 +77,7 @@ android { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } - + viewBinding { enabled = true } From 6ea67e11fb2d0181d35ed761d2470aaacdaaa9c0 Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Tue, 22 Jul 2025 22:15:45 +0530 Subject: [PATCH 10/20] fix: product flavor compatibility issue with code assist --- app/build.gradle | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 6400dbe1..62e5e639 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -14,21 +14,6 @@ android { versionName "0.1.0-Alpha" } - flavorDimensions "default" - - productFlavors { - dev { - dimension "default" - applicationIdSuffix ".dev" - versionNameSuffix "-Dev" - manifestPlaceholders = [appIcon: "@mipmap/dev_ic_launcher", appLabel: "Devpasscode"] // the name come from a parent project name "PassCodes" - } - prod { - dimension "default" - manifestPlaceholders = [appIcon: "@mipmap/ic_launcher", appLabel: "@string/app_name"] - } - } - signingConfigs { release { def keystorePropertiesFile = rootProject.file("keystore.properties") @@ -66,10 +51,40 @@ android { if (rootProject.file("keystore.properties").exists()) { signingConfig signingConfigs.release } + + minifyEnabled true + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + + manifestPlaceholders = [ + appIcon: "@mipmap/ic_launcher", + appLabel: "@string/app_name" + ] + } + + debug { + applicationIdSuffix ".dev" + versionNameSuffix "-Dev" + minifyEnabled false + // the name come from a parent project name "PassCodes" + manifestPlaceholders = [ + appIcon: "@mipmap/dev_ic_launcher", + appLabel: "Passcodes Dev" + ] + } + + staging { + applicationIdSuffix ".staging" + versionNameSuffix "-Staging" + minifyEnabled true + debuggable true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + manifestPlaceholders = [ + appIcon: "@mipmap/dev_ic_launcher", + appLabel: "Passcodes Stageing" + ] } } From b4e6586a37c4857ddd788f688a319b5cd1362f7d Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Tue, 22 Jul 2025 22:20:07 +0530 Subject: [PATCH 11/20] docs: create a way to easily access commands --- commands.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 commands.md diff --git a/commands.md b/commands.md new file mode 100644 index 00000000..35d7433e --- /dev/null +++ b/commands.md @@ -0,0 +1,15 @@ +```powershell +./gradlew clean assembleRelease +``` + +```powershell +./gradlew assembleStaging +``` + +```powershell +./gradlew assembleDebug +``` + +```powershell +./gradlew clean +``` From 3a6fffc7a838ae9c1c3c460f443fa14cb08146b0 Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Wed, 23 Jul 2025 19:26:31 +0530 Subject: [PATCH 12/20] Disable Buttons --- app/src/main/res/layout/activity_password_manager.xml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app/src/main/res/layout/activity_password_manager.xml b/app/src/main/res/layout/activity_password_manager.xml index e5c1210a..848650a5 100644 --- a/app/src/main/res/layout/activity_password_manager.xml +++ b/app/src/main/res/layout/activity_password_manager.xml @@ -31,6 +31,7 @@ android:textSize="14dp" /> Date: Wed, 23 Jul 2025 21:07:43 +0530 Subject: [PATCH 13/20] fix: code assist compatibility with seperate manifest file --- app/build.gradle | 16 ---------------- app/src/debug/AndroidManifest.xml | 10 ++++++++++ app/src/main/AndroidManifest.xml | 4 ++-- app/src/staging/AndroidManifest.xml | 10 ++++++++++ 4 files changed, 22 insertions(+), 18 deletions(-) create mode 100644 app/src/debug/AndroidManifest.xml create mode 100644 app/src/staging/AndroidManifest.xml diff --git a/app/build.gradle b/app/build.gradle index 62e5e639..c9f76426 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -54,23 +54,12 @@ android { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - - manifestPlaceholders = [ - appIcon: "@mipmap/ic_launcher", - appLabel: "@string/app_name" - ] } debug { applicationIdSuffix ".dev" versionNameSuffix "-Dev" minifyEnabled false - - // the name come from a parent project name "PassCodes" - manifestPlaceholders = [ - appIcon: "@mipmap/dev_ic_launcher", - appLabel: "Passcodes Dev" - ] } staging { @@ -80,11 +69,6 @@ android { minifyEnabled true debuggable true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' - - manifestPlaceholders = [ - appIcon: "@mipmap/dev_ic_launcher", - appLabel: "Passcodes Stageing" - ] } } diff --git a/app/src/debug/AndroidManifest.xml b/app/src/debug/AndroidManifest.xml new file mode 100644 index 00000000..0bb65c24 --- /dev/null +++ b/app/src/debug/AndroidManifest.xml @@ -0,0 +1,10 @@ + + + + + diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index c100584f..3f0b9d84 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -18,8 +18,8 @@ + + + + From b6871afeafe20289a09db9d0a5b2792bc4dc3df4 Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Wed, 23 Jul 2025 21:18:57 +0530 Subject: [PATCH 14/20] Revert "fix: code assist compatibility with seperate manifest file" This reverts commit 5342a77fc525879c596d398100134b7ef018b9e8. --- app/build.gradle | 16 ++++++++++++++++ app/src/debug/AndroidManifest.xml | 10 ---------- app/src/main/AndroidManifest.xml | 4 ++-- app/src/staging/AndroidManifest.xml | 10 ---------- 4 files changed, 18 insertions(+), 22 deletions(-) delete mode 100644 app/src/debug/AndroidManifest.xml delete mode 100644 app/src/staging/AndroidManifest.xml diff --git a/app/build.gradle b/app/build.gradle index c9f76426..62e5e639 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -54,12 +54,23 @@ android { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + + manifestPlaceholders = [ + appIcon: "@mipmap/ic_launcher", + appLabel: "@string/app_name" + ] } debug { applicationIdSuffix ".dev" versionNameSuffix "-Dev" minifyEnabled false + + // the name come from a parent project name "PassCodes" + manifestPlaceholders = [ + appIcon: "@mipmap/dev_ic_launcher", + appLabel: "Passcodes Dev" + ] } staging { @@ -69,6 +80,11 @@ android { minifyEnabled true debuggable true proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + + manifestPlaceholders = [ + appIcon: "@mipmap/dev_ic_launcher", + appLabel: "Passcodes Stageing" + ] } } diff --git a/app/src/debug/AndroidManifest.xml b/app/src/debug/AndroidManifest.xml deleted file mode 100644 index 0bb65c24..00000000 --- a/app/src/debug/AndroidManifest.xml +++ /dev/null @@ -1,10 +0,0 @@ - - - - - diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3f0b9d84..c100584f 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -18,8 +18,8 @@ - - - - From 630747642dcf5395866369ede1382d8d7139e910 Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Wed, 23 Jul 2025 21:21:17 +0530 Subject: [PATCH 15/20] chore: Update installondevice.bat --- installondevice.bat | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/installondevice.bat b/installondevice.bat index 637b619f..5e97807d 100644 --- a/installondevice.bat +++ b/installondevice.bat @@ -3,14 +3,14 @@ @REM Force continuation after Gradle command by capturing the output if "%~1"=="prod" ( echo building a production build - call gradlew clean assembleProdRelease + call gradlew clean assembleRelease if ERRORLEVEL 1 ( echo Gradle build failed! Check build_output.txt for details. exit /b 1 ) ) else ( echo building a development build - call gradlew assembleDevDebug + call gradlew assembleDebug if ERRORLEVEL 1 ( echo Gradle build failed! Check build_output.txt for details. exit /b 1 @@ -35,14 +35,14 @@ if ERRORLEVEL 1 ( @REM Install the APK on the connected device if "%~1"=="prod" ( echo Installing a production apk - adb install ./app/build/outputs/apk/prod/release/app-prod-universal-release.apk + adb install ./app/build/outputs/apk/release/app-universal-release.apk if ERRORLEVEL 1 ( echo Gradle build failed! Check build_output.txt for details. exit /b 1 ) ) else ( echo Installing a dev apk - adb install ./app/build/outputs/apk/dev/debug/app-dev-universal-debug.apk + adb install ./app/build/outputs/apk/debug/app-universal-debug.apk if ERRORLEVEL 1 ( echo Gradle build failed! Check build_output.txt for details. exit /b 1 From f7eade4a3ef445d3d867395a823fc1035fe5f2b5 Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Thu, 24 Jul 2025 11:02:32 +0530 Subject: [PATCH 16/20] docs: improved docs for developers --- commands.md | 15 --------------- docs/building.md | 6 +++--- docs/commands.md | 31 +++++++++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 18 deletions(-) delete mode 100644 commands.md create mode 100644 docs/commands.md diff --git a/commands.md b/commands.md deleted file mode 100644 index 35d7433e..00000000 --- a/commands.md +++ /dev/null @@ -1,15 +0,0 @@ -```powershell -./gradlew clean assembleRelease -``` - -```powershell -./gradlew assembleStaging -``` - -```powershell -./gradlew assembleDebug -``` - -```powershell -./gradlew clean -``` diff --git a/docs/building.md b/docs/building.md index e0e73bc8..9cfcf86c 100644 --- a/docs/building.md +++ b/docs/building.md @@ -10,20 +10,20 @@ You will need `gradle` and `adb` accessible from commandline so, that script can something like this... ``` -PS C:\Users\HP> gradle help +PS C:\Users\ABC> gradle help > Task :help Welcome to Gradle 8.9. -Directory 'C:\Users\HP' does not contain a Gradle build. +Directory 'C:\Users\ABC' does not contain a Gradle build. .... BUILD SUCCESSFUL in 1s 1 actionable task: 1 executed -PS C:\Users\HP> adb help +PS C:\Users\ABC> adb help Android Debug Bridge version 1.0.41 Version 35.0.2-12147458 Installed as C:...\cmdline-tools\lib\platform-tools\adb.exe diff --git a/docs/commands.md b/docs/commands.md new file mode 100644 index 00000000..5f525342 --- /dev/null +++ b/docs/commands.md @@ -0,0 +1,31 @@ +# Important Commads + +- For Building A Clean ALL Variant + +```powershell +./gradlew clean assemble +``` + +- For Building A Clean Release Variant + +```powershell +./gradlew clean assembleRelease +``` + +- For Building A Staging Variant + +```powershell +./gradlew assembleStaging +``` + +- For Building A Debug Variant + +```powershell +./gradlew assembleDebug +``` + +- For Clearing Build Files + +```powershell +./gradlew clean +``` From 3f7a1c0b943086a4633d061be701afddb9d4283e Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Thu, 24 Jul 2025 11:27:13 +0530 Subject: [PATCH 17/20] docs: git-hooks --- git-hooks/commit-msg.sample | 46 +++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 git-hooks/commit-msg.sample diff --git a/git-hooks/commit-msg.sample b/git-hooks/commit-msg.sample new file mode 100644 index 00000000..d94cc1ef --- /dev/null +++ b/git-hooks/commit-msg.sample @@ -0,0 +1,46 @@ +#!/usr/bin/env bash + +# Path to the commit message file (provided by Git). +COMMIT_MSG_FILE=$1 + +# Ignore automatic commit messages containing ' into ' or 'Merge'. +if grep --quiet --extended-regexp " into |^Merge " "$COMMIT_MSG_FILE"; then + exit 0 +fi + +# Read the commit message from the file. +COMMIT_MSG=$(cat "$COMMIT_MSG_FILE") + +CONVENTIONAL_COMMIT_REGEX='^(feat|fix|docs|style|refactor|test|chore|build|ci|perf|revert)(\([a-zA-Z0-9_.-]+\))?(!)?:\s.*$' + +# Check if the commit message matches the regex. +if ! [[ $COMMIT_MSG =~ $CONVENTIONAL_COMMIT_REGEX ]]; then + echo "ERROR: Commit message does not follow Conventional Commits format." + echo + echo "The commit message should be structured as follows:" + echo "(): " + echo "[optional body]" + echo "[optional footer(s)]" + echo + echo "Valid types are:" + echo " feat: A new feature." + echo " fix: A bug fix." + echo " docs: Documentation changes." + echo " style: Code style changes (formatting, missing semicolons, etc.)." + echo " refactor: Code refactoring (neither fixes a bug nor adds a feature)." + echo " test: Adding or updating tests." + echo " chore: Routine tasks like updating dependencies or build tools." + echo " build: Changes affecting the build system or external dependencies." + echo " ci: Changes to CI configuration files or scripts." + echo " perf: Performance improvements." + echo " revert: Reverting a previous commit." + echo + echo "Examples:" + echo " feat(auth): add login functionality" + echo " fix(api)!: resolve timeout issue" + echo " docs(readme): update installation instructions" + echo + exit 1 +fi + +exit 0 From fb238149f3774207f1bcddf461446e3cc0224a3b Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Thu, 24 Jul 2025 15:27:31 +0530 Subject: [PATCH 18/20] test: setup unit tests --- app/build.gradle | 2 + .../utils/ExampleTestableCode.java | 17 +++++++ .../utils/ExampleTestableCodeTest.java | 50 +++++++++++++++++++ 3 files changed, 69 insertions(+) create mode 100644 app/src/main/java/com/passwordmanager/utils/ExampleTestableCode.java create mode 100644 app/src/test/java/com/passwordmanager/utils/ExampleTestableCodeTest.java diff --git a/app/build.gradle b/app/build.gradle index 62e5e639..633233b9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -103,4 +103,6 @@ dependencies { implementation 'androidx.appcompat:appcompat:1.6.1' implementation 'androidx.databinding:viewbinding:7.4.1' implementation 'org.json:json:20250517' + + testImplementation 'junit:junit:4.13.2' } diff --git a/app/src/main/java/com/passwordmanager/utils/ExampleTestableCode.java b/app/src/main/java/com/passwordmanager/utils/ExampleTestableCode.java new file mode 100644 index 00000000..32c57ae4 --- /dev/null +++ b/app/src/main/java/com/passwordmanager/utils/ExampleTestableCode.java @@ -0,0 +1,17 @@ +package com.passwordmanager.utils; + +class ExampleTestableCode { + int checkStrength(String password) { + if (password == null || password.isEmpty()) { + return -1; + } + + int length = password.length(); + + if (length < 8) { + return 0; + } else { + return 1; + } + } +} diff --git a/app/src/test/java/com/passwordmanager/utils/ExampleTestableCodeTest.java b/app/src/test/java/com/passwordmanager/utils/ExampleTestableCodeTest.java new file mode 100644 index 00000000..cd9c28ad --- /dev/null +++ b/app/src/test/java/com/passwordmanager/utils/ExampleTestableCodeTest.java @@ -0,0 +1,50 @@ +package com.passwordmanager.utils; + +import org.junit.Test; +import org.junit.Before; +import static org.junit.Assert.assertEquals; + +public class ExampleTestableCodeTest { + private ExampleTestableCode testObj; + + @Before + public void setup() { + testObj = new ExampleTestableCode(); + } + + @Test + public void testCheckStrength_With_EmptyPassword() { + // Given + String password = ""; + + // When + int strength = testObj.checkStrength(password); + + // // Then + assertEquals(1, 1); + } + + @Test + public void testCheckStrength_Weak_ShortPassword() { + // Given + String password = "short"; // Less than 8 characters + + // When + int strength = testObj.checkStrength(password); + + // Then + assertEquals(0, strength); + } + + @Test + public void testCheckStrength_Strong_LongPassword() { + // Given + String password = "long password"; // More than 8 characters + + // When + int strength = testObj.checkStrength(password); + + // Then + assertEquals(1, strength); + } +} From b972916a68ceba72336a25e453b6837eef7d4438 Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Thu, 24 Jul 2025 16:05:28 +0530 Subject: [PATCH 19/20] test: make them more readable with goggle truth --- app/build.gradle | 1 + .../utils/ExampleTestableCodeTest.java | 23 ++++++------------- 2 files changed, 8 insertions(+), 16 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 633233b9..c6418701 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -105,4 +105,5 @@ dependencies { implementation 'org.json:json:20250517' testImplementation 'junit:junit:4.13.2' + testImplementation "com.google.truth:truth:1.4.4" } diff --git a/app/src/test/java/com/passwordmanager/utils/ExampleTestableCodeTest.java b/app/src/test/java/com/passwordmanager/utils/ExampleTestableCodeTest.java index cd9c28ad..f983607b 100644 --- a/app/src/test/java/com/passwordmanager/utils/ExampleTestableCodeTest.java +++ b/app/src/test/java/com/passwordmanager/utils/ExampleTestableCodeTest.java @@ -2,7 +2,7 @@ import org.junit.Test; import org.junit.Before; -import static org.junit.Assert.assertEquals; +import static com.google.common.truth.Truth.assertThat; public class ExampleTestableCodeTest { private ExampleTestableCode testObj; @@ -17,11 +17,8 @@ public void testCheckStrength_With_EmptyPassword() { // Given String password = ""; - // When - int strength = testObj.checkStrength(password); - - // // Then - assertEquals(1, 1); + // When & Then + assertThat(testObj.checkStrength(password)).isEqualTo(-1); } @Test @@ -29,11 +26,8 @@ public void testCheckStrength_Weak_ShortPassword() { // Given String password = "short"; // Less than 8 characters - // When - int strength = testObj.checkStrength(password); - - // Then - assertEquals(0, strength); + // When & Then + assertThat(testObj.checkStrength(password)).isEqualTo(0); } @Test @@ -41,10 +35,7 @@ public void testCheckStrength_Strong_LongPassword() { // Given String password = "long password"; // More than 8 characters - // When - int strength = testObj.checkStrength(password); - - // Then - assertEquals(1, strength); + // When & Then + assertThat(testObj.checkStrength(password)).isEqualTo(1); } } From 8a2be4dbe34b6fbf51c4199df99306130639721f Mon Sep 17 00:00:00 2001 From: Jeel Dobariya Date: Thu, 24 Jul 2025 16:06:08 +0530 Subject: [PATCH 20/20] docs: add new command --- docs/commands.md | 28 +++++++++++++++++++++++----- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/docs/commands.md b/docs/commands.md index 5f525342..99c9f122 100644 --- a/docs/commands.md +++ b/docs/commands.md @@ -2,30 +2,48 @@ - For Building A Clean ALL Variant -```powershell +```bash ./gradlew clean assemble ``` - For Building A Clean Release Variant -```powershell +```bash ./gradlew clean assembleRelease ``` - For Building A Staging Variant -```powershell +```bash ./gradlew assembleStaging ``` - For Building A Debug Variant -```powershell +```bash ./gradlew assembleDebug ``` - For Clearing Build Files -```powershell +```bash ./gradlew clean ``` + +- For sync depeendency + +```bash +./gradlew --refresh-dependencies +``` + +- For test app + +```bash +./gradlew testDebugUnitTest +``` + +- For install app on usb connect device + +```bash +./gradlew installDebug +```