From 0ce2de37e7b7af4fbcc34990f74f91476fb9e387 Mon Sep 17 00:00:00 2001 From: 4f77616973 <0x4f@tuta.io> Date: Thu, 12 Jan 2023 20:06:15 +0530 Subject: [PATCH 1/8] cleaned PR template --- .github/pull_request_template.md | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 6a93ddd..c711e5f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -6,23 +6,18 @@ *Describe the proposed solution and changes. How does it affect the project? How does it affect the internal structure (e.g., refactorings)?* -## 📷: Screenshots +## 📷 Screenshots *Provide screenshots showcasing the changes before and after the proposed changes (if applicable).* -## 📋 : Release Notes +## 📚 Release Notes *Provide a summary of the changes or features from a user's point of view. If there are breaking changes, provide migration guides using code examples of the affected features.* - - -## :heavy_plus_sign: Additional Information -*If applicable, provide additional context in this section.* - -### Testing +### 📝 Testing *Which tests were added? Which existing tests were adapted/changed? Which situations are covered, and what edge cases are missing?* -### Reviewer Nudging +### 👉 Reviewer Nudging *Where should the reviewer start? what is a good entry point?* From 772d91523809554d3232173cff99b6421373a605 Mon Sep 17 00:00:00 2001 From: 4f77616973 <0x4f@tuta.io> Date: Thu, 12 Jan 2023 20:07:34 +0530 Subject: [PATCH 2/8] cleaned PR template --- .github/pull_request_template.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index c711e5f..017394b 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -14,10 +14,7 @@ *Provide a summary of the changes or features from a user's point of view. If there are breaking changes, provide migration guides using code examples of the affected features.* -### 📝 Testing +## 📝 Testing *Which tests were added? Which existing tests were adapted/changed? Which situations are covered, and what edge cases are missing?* -### 👉 Reviewer Nudging - -*Where should the reviewer start? what is a good entry point?* From 008b53a2a04a11c28787709936eaaf8568813eb8 Mon Sep 17 00:00:00 2001 From: 4f77616973 <0x4f@tuta.io> Date: Tue, 17 Jan 2023 01:59:53 +0530 Subject: [PATCH 3/8] added acra skeleton --- app/build.gradle | 10 +++-- app/proguard-rules.pro | 19 +++++++- app/src/main/AndroidManifest.xml | 1 + .../kotlin/cloud/keyspace/android/Keyspace.kt | 44 +++++++++++++++++++ .../cloud/keyspace/android/StartHere.kt | 3 +- app/src/main/res/values/strings.xml | 3 +- 6 files changed, 73 insertions(+), 7 deletions(-) create mode 100644 app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt diff --git a/app/build.gradle b/app/build.gradle index 22699d1..668650b 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -51,7 +51,7 @@ android { dependencies { implementation 'com.android.support:multidex:2.0.1' // noinspection GradleDependency implementation 'androidx.core:core-ktx:1.9.0' // Default Android stuff - implementation 'androidx.appcompat:appcompat:1.5.1' + implementation 'androidx.appcompat:appcompat:1.6.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.4' implementation 'androidx.legacy:legacy-support-v4:1.0.0' implementation 'androidx.gridlayout:gridlayout:1.0.0' @@ -67,8 +67,8 @@ dependencies { implementation 'androidx.core:core-ktx:1.9.0' testImplementation 'junit:junit:4.13.2' // Testing implementation 'androidx.biometric:biometric:1.2.0-alpha05' // Biometrics - androidTestImplementation 'androidx.test.ext:junit:1.1.4' - androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.0' + androidTestImplementation 'androidx.test.ext:junit:1.1.5' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1' implementation 'com.google.android.material:material:1.7.0' // Material design implementation 'androidx.fragment:fragment-ktx:1.5.5' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.6.4' @@ -99,4 +99,8 @@ dependencies { implementation 'com.scottyab:rootbeer-lib:0.1.0' // To check if device is rooted implementation "androidx.core:core-splashscreen:1.0.0" // Splash screen library implementation 'com.nulab-inc:zxcvbn:1.7.0' // password strength + + // ACRA for crash logging + implementation 'ch.acra:acra-mail:5.9.7' // mail component + implementation 'ch.acra:acra-toast:5.9.7' // dialog component } \ No newline at end of file diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 481bb43..63ab79d 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -18,4 +18,21 @@ # If you keep the line number information, uncomment this to # hide the original source file name. -#-renamesourcefileattribute SourceFile \ No newline at end of file +#-renamesourcefileattribute SourceFile + +#ACRA specifics +# Restore some Source file names and restore approximate line numbers in the stack traces, +# otherwise the stack traces are pretty useless +-keepattributes SourceFile, LineNumberTable + +# ACRA needs "annotations" so add this... +# Note: This may already be defined in the default "proguard-android-optimize.txt" +# file in the SDK. If it is, then you don't need to duplicate it. See your +# "project.properties" file to get the path to the default "proguard-android-optimize.txt". +-keepattributes *Annotation* + +# Keep all the ACRA classes +-keep class org.acra.** { *; } + +# Don't warn about removed methods from AppCompat +-dontwarn android.support.v4.app.NotificationCompat* \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2239f5f..1014235 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,6 +20,7 @@ android:fullBackupContent="false" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" + android:name="cloud.keyspace.android.Keyspace" android:largeHeap="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" diff --git a/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt b/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt new file mode 100644 index 0000000..0672e2c --- /dev/null +++ b/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt @@ -0,0 +1,44 @@ +package cloud.keyspace.android + +import android.app.Application +import android.content.Context +import android.widget.Toast +import org.acra.config.mailSenderConfiguration +import org.acra.config.toastConfiguration +import org.acra.data.StringFormat +import org.acra.ktx.initAcra + +class Keyspace : Application() { + override fun attachBaseContext(base: Context) { + super.attachBaseContext(base) + + initAcra { + buildConfigClass = BuildConfig::class.java + reportFormat = StringFormat.JSON + + toastConfiguration { // Todo replace with dialog or notification + //required + text = getString(R.string.crash_send_logs_description) + //defaults to Toast.LENGTH_LONG + length = Toast.LENGTH_LONG + enabled = true + } + + mailSenderConfiguration { + //required + mailTo = "acra@yourserver.com" + //defaults to true + reportAsFile = true + //defaults to ACRA-report.stacktrace + reportFileName = "Crash.txt" + //defaults to " Crash Report" + subject = getString(R.string.crash_send_logs_description) + //defaults to empty + body = getString(R.string.crash_send_logs_description) + enabled = true + } + + } + + } +} \ No newline at end of file diff --git a/app/src/main/kotlin/cloud/keyspace/android/StartHere.kt b/app/src/main/kotlin/cloud/keyspace/android/StartHere.kt index f3892f1..7c461fd 100644 --- a/app/src/main/kotlin/cloud/keyspace/android/StartHere.kt +++ b/app/src/main/kotlin/cloud/keyspace/android/StartHere.kt @@ -61,8 +61,6 @@ import kotlinx.coroutines.* import java.io.File import java.util.* import java.util.concurrent.Executor -import kotlin.system.exitProcess - private lateinit var _supportFragmentManager: FragmentManager @@ -1656,6 +1654,7 @@ class StartHere : AppCompatActivity() { override fun onAnimationStart(animation: Animation) { authenticateTitle.setText("All done!") authenticateDescription.setText("daaaammn if you can read this you have eagle eyes... \uD83E\uDD85") + throw ArrayIndexOutOfBoundsException() } override fun onAnimationRepeat(animation: Animation) { } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index acb455a..cbce790 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -33,7 +33,6 @@ Your Vault is kept secure using your device lock and is only decrypted when you unlock Keyspace. If your device has a fingerprint sensor or facial recognition, we recommend setting it up for your convenience.\n\nTap the button below to unlock. Your Vault is kept secure using your biometrics and is only decrypted when you unlock Keyspace.\n\nTap the button below to unlock. - Enter a passphrase Make sure it\'s strong Your Keyspace passphrase is an advanced security feature that lets you strengthen your account\'s security.\n\nThis step is optional. @@ -116,4 +115,6 @@ Verify that the words are in the exact order as given with proper spelling Store your recovery phrase in a secure location and make sure only you can access it + Keyspace just crashed. Would you like to email crash logs to the team? + \ No newline at end of file From 1a940c5535a42d258ae9efa597ebb22c88e0a92b Mon Sep 17 00:00:00 2001 From: 4f77616973 <0x4f@tuta.io> Date: Tue, 17 Jan 2023 16:49:24 +0530 Subject: [PATCH 4/8] implemented crash handler --- app/build.gradle | 2 +- .../kotlin/cloud/keyspace/android/Keyspace.kt | 38 +++++++++---------- app/src/main/res/values/strings.xml | 14 ++++++- 3 files changed, 31 insertions(+), 23 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 668650b..627e21f 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -102,5 +102,5 @@ dependencies { // ACRA for crash logging implementation 'ch.acra:acra-mail:5.9.7' // mail component - implementation 'ch.acra:acra-toast:5.9.7' // dialog component + implementation 'ch.acra:acra-dialog:5.9.7' // dialog component } \ No newline at end of file diff --git a/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt b/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt index 0672e2c..55612d8 100644 --- a/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt +++ b/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt @@ -2,40 +2,36 @@ package cloud.keyspace.android import android.app.Application import android.content.Context -import android.widget.Toast -import org.acra.config.mailSenderConfiguration -import org.acra.config.toastConfiguration +import org.acra.config.dialog +import org.acra.config.mailSender import org.acra.data.StringFormat import org.acra.ktx.initAcra +import java.sql.Time +import java.time.Instant +import java.time.format.DateTimeFormatter class Keyspace : Application() { override fun attachBaseContext(base: Context) { super.attachBaseContext(base) - initAcra { buildConfigClass = BuildConfig::class.java - reportFormat = StringFormat.JSON + reportFormat = StringFormat.KEY_VALUE_LIST - toastConfiguration { // Todo replace with dialog or notification - //required + dialog { text = getString(R.string.crash_send_logs_description) - //defaults to Toast.LENGTH_LONG - length = Toast.LENGTH_LONG - enabled = true + title = " " + getString(R.string.app_name) + positiveButtonText = getString(R.string.crash_send_positive_button_text) + negativeButtonText = getString(R.string.exit) + resIcon = R.drawable.keyspace + resTheme = android.R.style.Theme_Material_Dialog } - mailSenderConfiguration { - //required - mailTo = "acra@yourserver.com" - //defaults to true + mailSender { + mailTo = getString(R.string.support_email) reportAsFile = true - //defaults to ACRA-report.stacktrace - reportFileName = "Crash.txt" - //defaults to " Crash Report" - subject = getString(R.string.crash_send_logs_description) - //defaults to empty - body = getString(R.string.crash_send_logs_description) - enabled = true + reportFileName = "bug_report_${DateTimeFormatter.ISO_INSTANT.format(Instant.now())}.txt" + subject = getString(R.string.crash_send_logs_email_subject) + body = getString(R.string.crash_send_logs_email_body) } } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index cbce790..5b4d459 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -115,6 +115,18 @@ Verify that the words are in the exact order as given with proper spelling Store your recovery phrase in a secure location and make sure only you can access it - Keyspace just crashed. Would you like to email crash logs to the team? + Keyspace Android app crash + This email contains a bug report of a recent crash on Keyspace Android. + Keyspace + Send email + Uh oh, Keyspace just crashed. Would you like to send a bug report to the team?\n\n + + This bug report will include:\n\n + + ⋅ Device information (such model, Android version etc.)\n + ⋅ App-related crash logs and exceptions\n\n + + This is optional. + \ No newline at end of file From 4e4ece05c021e4b4dfaa52fc7f24495b3e6fc314 Mon Sep 17 00:00:00 2001 From: 4f77616973 <0x4f@tuta.io> Date: Tue, 17 Jan 2023 23:57:25 +0530 Subject: [PATCH 5/8] removed generic exception handlers --- .../cloud/keyspace/android/StartHere.kt | 150 ++++++++---------- 1 file changed, 62 insertions(+), 88 deletions(-) diff --git a/app/src/main/kotlin/cloud/keyspace/android/StartHere.kt b/app/src/main/kotlin/cloud/keyspace/android/StartHere.kt index 7c461fd..8e19bff 100644 --- a/app/src/main/kotlin/cloud/keyspace/android/StartHere.kt +++ b/app/src/main/kotlin/cloud/keyspace/android/StartHere.kt @@ -373,15 +373,10 @@ class StartHere : AppCompatActivity() { loadingScreenFragmentView = inflater.inflate(R.layout.loading_screen, container, false) loadContent() - try { - generateCryptoObjects() - // logger() - if (mode == MODE_CREATE_ACCOUNT) createAccount() - else if (mode == MODE_SIGN_IN) signIn() + generateCryptoObjects() - } catch (unknownError: Exception) { - showCryptographyErrorDialog() - } + if (mode == MODE_CREATE_ACCOUNT) createAccount() + else if (mode == MODE_SIGN_IN) signIn() return loadingScreenFragmentView @@ -437,49 +432,39 @@ class StartHere : AppCompatActivity() { delay (500) setKeygen() - try { - generateCryptoObjects() - - keygenToSend() - delay(500) - - CoroutineScope(Dispatchers.IO).launch { - kotlin.runCatching { - val vaultData = network.grabLatestVaultFromBackend (signedToken) - withContext(Dispatchers.Main) { // used to run synchronous Kotlin functions like `suspend fun foo()` - sendToReceive() - - io.writeVault(vaultData) - - delay(500) - receiveToKeystore() - storeToKeyring() - delay (1000) - - keystoreToTick() - delay (3000) - - startPermissions() - } - }.onFailure { - when (it) { - is NetworkUtilities.IncorrectCredentialsException -> { - withContext(Dispatchers.Main) { - showIncorrectCredentialsDialog() - } + generateCryptoObjects() + keygenToSend() + delay(500) + + CoroutineScope(Dispatchers.IO).launch { + kotlin.runCatching { + val vaultData = network.grabLatestVaultFromBackend (signedToken) + withContext(Dispatchers.Main) { // used to run synchronous Kotlin functions like `suspend fun foo()` + sendToReceive() + io.writeVault(vaultData) + delay(500) + receiveToKeystore() + storeToKeyring() + delay (1000) + keystoreToTick() + delay (3000) + startPermissions() + } + }.onFailure { + when (it) { + is NetworkUtilities.IncorrectCredentialsException -> { + withContext(Dispatchers.Main) { + showIncorrectCredentialsDialog() } - is NetworkError -> { - withContext(Dispatchers.Main) { - showNetworkErrorDialog() - } + } + is NetworkError -> { + withContext(Dispatchers.Main) { + showNetworkErrorDialog() } - else -> throw it } + else -> throw it } } - - } catch (unknownError: Exception) { - showCryptographyErrorDialog () } } @@ -497,54 +482,44 @@ class StartHere : AppCompatActivity() { delay (500) setKeygen() - try { - generateCryptoObjects() + generateCryptoObjects() + keygenToSend() - keygenToSend() - CoroutineScope(Dispatchers.IO).launch { - kotlin.runCatching { - val createAccountResponse: NetworkUtilities.SignupResponse = network.sendSignupRequest( - NetworkUtilities.SignupParameters( - email = email, - public_key = publicKey.toHexString(), - signed_token = signedToken - ) - )!! - - if (createAccountResponse.status != network.RESPONSE_SUCCESS) throw NetworkUtilities.AccountExistsException() else { - withContext(Dispatchers.Main) { // used to run synchronous Kotlin functions like `suspend fun foo()` - delay(1000) - - receiveToKeystore() - storeToKeyring() - delay (1000) - - keystoreToTick() - delay (3000) - - startPermissions() - } + CoroutineScope(Dispatchers.IO).launch { + kotlin.runCatching { + val createAccountResponse: NetworkUtilities.SignupResponse = network.sendSignupRequest( + NetworkUtilities.SignupParameters( + email = email, + public_key = publicKey.toHexString(), + signed_token = signedToken + ) + )!! + if (createAccountResponse.status != network.RESPONSE_SUCCESS) throw NetworkUtilities.AccountExistsException() else { + withContext(Dispatchers.Main) { // used to run synchronous Kotlin functions like `suspend fun foo()` + delay(1000) + receiveToKeystore() + storeToKeyring() + delay (1000) + keystoreToTick() + delay (3000) + startPermissions() } - - }.onFailure { - when (it) { - is NetworkUtilities.AccountExistsException -> { - withContext(Dispatchers.Main) { - showDuplicateAccountDialog() - } + } + }.onFailure { + when (it) { + is NetworkUtilities.AccountExistsException -> { + withContext(Dispatchers.Main) { + showDuplicateAccountDialog() } - is NetworkError -> { - withContext(Dispatchers.Main) { - showNetworkErrorDialog() - } + } + is NetworkError -> { + withContext(Dispatchers.Main) { + showNetworkErrorDialog() } - else -> throw it } + else -> throw it } } - - } catch (unknownError: Exception) { - showCryptographyErrorDialog () } } @@ -1654,7 +1629,6 @@ class StartHere : AppCompatActivity() { override fun onAnimationStart(animation: Animation) { authenticateTitle.setText("All done!") authenticateDescription.setText("daaaammn if you can read this you have eagle eyes... \uD83E\uDD85") - throw ArrayIndexOutOfBoundsException() } override fun onAnimationRepeat(animation: Animation) { } From 5bc31a5e3131fdce41e2e888e7f23239f8b9d9ae Mon Sep 17 00:00:00 2001 From: 4f77616973 <0x4f@tuta.io> Date: Tue, 17 Jan 2023 23:58:52 +0530 Subject: [PATCH 6/8] removed generic exception handlers --- app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt b/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt index 55612d8..4eb840c 100644 --- a/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt +++ b/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt @@ -6,7 +6,6 @@ import org.acra.config.dialog import org.acra.config.mailSender import org.acra.data.StringFormat import org.acra.ktx.initAcra -import java.sql.Time import java.time.Instant import java.time.format.DateTimeFormatter From bb6e0787a22d3bb724d80dca6844d721ccdd97e2 Mon Sep 17 00:00:00 2001 From: 4f77616973 <0x4f@tuta.io> Date: Thu, 19 Jan 2023 22:58:44 +0530 Subject: [PATCH 7/8] added an email subject prefix --- app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt | 2 +- app/src/main/res/values/strings.xml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt b/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt index 4eb840c..c4d7fdd 100644 --- a/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt +++ b/app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt @@ -28,7 +28,7 @@ class Keyspace : Application() { mailSender { mailTo = getString(R.string.support_email) reportAsFile = true - reportFileName = "bug_report_${DateTimeFormatter.ISO_INSTANT.format(Instant.now())}.txt" + reportFileName = "android_bug_report_${DateTimeFormatter.ISO_INSTANT.format(Instant.now())}.txt" subject = getString(R.string.crash_send_logs_email_subject) body = getString(R.string.crash_send_logs_email_body) } diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 5b4d459..7655ac2 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -115,8 +115,8 @@ Verify that the words are in the exact order as given with proper spelling Store your recovery phrase in a secure location and make sure only you can access it - Keyspace Android app crash - This email contains a bug report of a recent crash on Keyspace Android. + [KEYSPACE-ANDROID-CRASH] Keyspace Android crashes on my device + This email contains a bug report of a recent crash I encountered on Keyspace Android. Keyspace Send email Uh oh, Keyspace just crashed. Would you like to send a bug report to the team?\n\n From d24ff2c3f4d8c1e0ee652c0644c08802eb356cba Mon Sep 17 00:00:00 2001 From: Owais Shaikh <71916237+4f77616973@users.noreply.github.com> Date: Thu, 2 Feb 2023 05:25:40 +0530 Subject: [PATCH 8/8] Update app/src/main/res/values/strings.xml Co-authored-by: Rohan Chaturvedi --- app/src/main/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 7655ac2..e32d826 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -123,7 +123,7 @@ This bug report will include:\n\n - ⋅ Device information (such model, Android version etc.)\n + ⋅ Device information (such as model, Android version etc.)\n ⋅ App-related crash logs and exceptions\n\n This is optional.