Skip to content
This repository was archived by the owner on Jan 25, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 3 additions & 11 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,15 @@

*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

*Where should the reviewer start? what is a good entry point?*
10 changes: 7 additions & 3 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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'
Expand Down Expand Up @@ -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-dialog:5.9.7' // dialog component
}
19 changes: 18 additions & 1 deletion app/proguard-rules.pro
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,21 @@

# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
#-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*
1 change: 1 addition & 0 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
39 changes: 39 additions & 0 deletions app/src/main/kotlin/cloud/keyspace/android/Keyspace.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package cloud.keyspace.android

import android.app.Application
import android.content.Context
import org.acra.config.dialog
import org.acra.config.mailSender
import org.acra.data.StringFormat
import org.acra.ktx.initAcra
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.KEY_VALUE_LIST

dialog {
text = getString(R.string.crash_send_logs_description)
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
}

mailSender {
mailTo = getString(R.string.support_email)
reportAsFile = true
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)
}

}

}
}
151 changes: 62 additions & 89 deletions app/src/main/kotlin/cloud/keyspace/android/StartHere.kt
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -375,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

Expand Down Expand Up @@ -439,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 ()
}

}
Expand All @@ -499,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 ()
}

}
Expand Down
15 changes: 14 additions & 1 deletion app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
<string name="blurbDescriptionDeviceLock">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.</string>
<string name="blurbDescriptionBiometrics">Your Vault is kept secure using your biometrics and is only decrypted when you unlock Keyspace.\n\nTap the button below to unlock.</string>

<string></string>
<string name="passphrase_error">Enter a passphrase</string>
<string name="subtitlePassphrase">Make sure it\'s strong</string>
<string name="descriptionPassphrase">Your Keyspace passphrase is an advanced security feature that lets you strengthen your account\'s security.\n\nThis step is optional.</string>
Expand Down Expand Up @@ -116,4 +115,18 @@
<string name="verify_words_text">Verify that the words are in the <b>exact order</b> as given with proper spelling</string>
<string name="safeguard_words_text">Store your recovery phrase in a secure location and make sure only you can access it</string>

<string name="crash_send_logs_email_subject">[KEYSPACE-ANDROID-CRASH] Keyspace Android crashes on my device</string>
<string name="crash_send_logs_email_body">This email contains a bug report of a recent crash I encountered on Keyspace Android.</string>
<string name="crash_send_logs_title">Keyspace</string>
<string name="crash_send_positive_button_text">Send email</string>
<string name="crash_send_logs_description">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 as model, Android version etc.)\n
⋅ App-related crash logs and exceptions\n\n

This is optional.
</string>

</resources>