Skip to content
This repository was archived by the owner on Jan 25, 2025. It is now read-only.

Commit ef32497

Browse files
authored
Merge pull request #10 from Keyspace-cloud/onboarding-bugfixes
Onboarding bugfixes
2 parents f1a0f2f + dc393fb commit ef32497

File tree

22 files changed

+454
-595
lines changed

22 files changed

+454
-595
lines changed

.gradle/7.6/checksums/checksums.lock

17 Bytes
Binary file not shown.
Binary file not shown.

.gradle/7.6/dependencies-accessors/gc.properties

Whitespace-only changes.
Binary file not shown.
Binary file not shown.
1 Byte
Binary file not shown.

.gradle/7.6/fileHashes/fileHashes.bin

548 KB
Binary file not shown.
17 Bytes
Binary file not shown.
175 KB
Binary file not shown.

.gradle/7.6/gc.properties

Whitespace-only changes.
Binary file not shown.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
#Wed Dec 21 09:42:07 IST 2022
2+
gradle.version=7.6
291 KB
Binary file not shown.

.gradle/file-system.probe

8 Bytes
Binary file not shown.

.gradle/vcs-1/gc.properties

Whitespace-only changes.

.idea/modules/app/Keyspace.app.main.iml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@ android {
1010
applicationId "cloud.keyspace.android"
1111
minSdkVersion 27
1212
targetSdkVersion 33
13-
versionCode 12
14-
versionName "1.2"
13+
versionCode 13
14+
versionName "1.3"
1515
multiDexEnabled true
1616

1717
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"

app/src/main/kotlin/cloud/keyspace/android/Dashboard.kt

Lines changed: 21 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2842,59 +2842,42 @@ class Dashboard : AppCompatActivity(), NavigationView.OnNavigationItemSelectedLi
28422842
connectionStatusDot.visibility = View.GONE
28432843

28442844
lateinit var signedToken: String
2845+
28452846
try {
28462847
signedToken = network.generateSignedToken()
28472848
} catch (_: Exception) {
28482849
cancel()
28492850
}
28502851

2851-
val serverVault = network.grabLatestVaultFromBackend (signedToken, configData.getString("userEmail", null)!!)
2852-
2853-
when (serverVault.second) {
2854-
network.RESPONSE_VAULT_CORRUPT -> {
2855-
cancel()
2856-
errorDialog (
2857-
"Vault corrupt",
2858-
"Your vault appears to be corrupt. This shouldn't be possible. Please contact Keyspace support for assistance.",
2859-
getDrawable(R.drawable.ic_baseline_error_24)!!
2860-
)
2861-
}
2862-
network.NETWORK_ERROR -> { cancel() }
2863-
else -> {
2864-
2865-
connectionStatusDot.visibility = View.GONE
2866-
2867-
if (io.vaultsDiffer(vault, serverVault.first!!)) {
2868-
2869-
io.writeVault(serverVault.first!!)
2870-
vault = serverVault.first!!
2871-
2872-
when {
2873-
2874-
(lastFragment == io.TYPE_LOGIN) -> {
2875-
renderLoginsFragment()
2876-
bottomNavbar.selectedItemId = R.id.logins
2877-
}
2852+
val serverVault = network.grabLatestVaultFromBackend (signedToken)
28782853

2879-
(lastFragment == io.TYPE_NOTE) -> {
2880-
renderNotesFragment()
2881-
bottomNavbar.selectedItemId = R.id.notes
2882-
}
2883-
2884-
(lastFragment == io.TYPE_CARD) -> {
2885-
renderCardsFragment()
2886-
bottomNavbar.selectedItemId = R.id.payments
2887-
}
2854+
connectionStatusDot.visibility = View.GONE
28882855

2889-
}
2856+
if (io.vaultsDiffer(vault, serverVault)) {
2857+
io.writeVault(serverVault)
2858+
vault = serverVault
2859+
when {
2860+
(lastFragment == io.TYPE_LOGIN) -> {
2861+
renderLoginsFragment()
2862+
bottomNavbar.selectedItemId = R.id.logins
2863+
}
2864+
(lastFragment == io.TYPE_NOTE) -> {
2865+
renderNotesFragment()
2866+
bottomNavbar.selectedItemId = R.id.notes
2867+
}
2868+
(lastFragment == io.TYPE_CARD) -> {
2869+
renderCardsFragment()
2870+
bottomNavbar.selectedItemId = R.id.payments
28902871
}
2891-
28922872
}
28932873
}
2874+
28942875
}
28952876

28962877
} catch (noInternet: NetworkError) {
28972878
cancel()
2879+
} catch (noInternet: NullPointerException) {
2880+
cancel()
28982881
}
28992882
}
29002883
}

app/src/main/kotlin/cloud/keyspace/android/NetworkUtilities.kt

Lines changed: 77 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import com.android.volley.*
1010
import com.android.volley.toolbox.JsonObjectRequest
1111
import com.android.volley.toolbox.StringRequest
1212
import com.android.volley.toolbox.Volley
13+
import com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException
1314
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
1415
import kotlinx.coroutines.*
1516
import org.json.JSONArray
@@ -157,7 +158,6 @@ class NetworkUtilities (
157158
}
158159

159160
fun completeQueueTasks (signedToken: String): Boolean {
160-
161161
var deleteQueueFile = File(applicationContext.cacheDir, deleteQueueFilename!!)
162162
val deleteQueueStream = FileOutputStream (deleteQueueFile, true)
163163
val deleteQueue: MutableList<String> = mutableListOf()
@@ -299,6 +299,8 @@ class NetworkUtilities (
299299
}
300300
}
301301

302+
class IncorrectCredentialsException : Exception()
303+
302304
/**
303305
* Make a synchronous GET request with an authorization header using Volley and Kotlin coroutines. The response from this function can be used on a UI thread.
304306
*
@@ -321,13 +323,19 @@ class NetworkUtilities (
321323
}
322324
}, { error ->
323325
error.printStackTrace()
324-
continuation.cancel (NetworkError())
326+
try {
327+
when (error.networkResponse.statusCode) {
328+
500 -> continuation.cancel (IncorrectCredentialsException())
329+
else -> continuation.cancel (NetworkError())
330+
}
331+
} catch (_: NullPointerException) {
332+
continuation.cancel (NetworkError())
333+
}
325334
Log.e("Keyspace", "Keyspace: Couldn't access this resource. Is it online and is your device connected to the internet?")
326335
}) {
327336
@Throws(AuthFailureError::class)
328337
override fun getHeaders(): Map<String, String> {
329338
val params: MutableMap<String, String> = HashMap()
330-
331339
// Headers are case insensitive
332340
params["public-key"] = keyring.ED25519_PUBLIC_KEY!!.toHexString()
333341
params["signed-token"] = signedToken
@@ -434,102 +442,76 @@ class NetworkUtilities (
434442
val RESPONSE_VAULT_DOES_NOT_EXIST = "RESPONSE_VAULT_DOES_NOT_EXIST"
435443
val RESPONSE_SUCCESS = "success"
436444

437-
suspend fun grabLatestVaultFromBackend (signedToken: String, email: String): Pair <IOUtilities.Vault?, String> {
445+
suspend fun grabLatestVaultFromBackend (signedToken: String): IOUtilities.Vault {
438446

439447
val io = IOUtilities(applicationContext, appCompatActivity, keyring)
440448
val freshVault = io.getVault()
441449

442450
var response: String? = null
443451
var vault: IOUtilities.Vault? = null
444-
lateinit var statusCode: String
445-
try {
446-
447-
val vaultData = synchronousGetRequestWithAuthorizationHeader (
448-
vault_items_endpoint,
449-
signedToken = signedToken
450-
)
451-
452-
val TYPE_LOGIN = "login"
453-
val TYPE_NOTE = "note"
454-
val TYPE_CARD = "card"
455-
val TYPE_TAG = "tag"
456-
457-
var vaultItemList = mutableListOf<String>()
458-
if (vaultData.toString().contains("corrupt")) throw InvalidObjectException(RESPONSE_VAULT_CORRUPT)
459-
460-
val data = JSONObject(vaultData?.get("data").toString())
461-
462-
var loginsJSONArray = JSONArray()
463-
var notesJSONArray = JSONArray()
464-
var cardsJSONArray = JSONArray()
465-
var tagsJSONArray = JSONArray()
466-
467-
try { loginsJSONArray = data.getJSONArray(TYPE_LOGIN) } catch (_: JSONException) {}
468-
try { notesJSONArray = data.getJSONArray(TYPE_NOTE) } catch (_: JSONException) {}
469-
try { cardsJSONArray = data.getJSONArray(TYPE_CARD) } catch (_: JSONException) {}
470-
try { tagsJSONArray = data.getJSONArray(TYPE_TAG) } catch (_: JSONException) {}
471-
472-
val logins: MutableList<IOUtilities.Login> = mutableListOf()
473-
val notes: MutableList<IOUtilities.Note> = mutableListOf()
474-
val cards: MutableList<IOUtilities.Card> = mutableListOf()
475-
val tags: MutableList<IOUtilities.Tag> = mutableListOf()
476-
477-
for (index in 0 until loginsJSONArray.length()) {
478-
val loginAsJSONObject = JSONObject(loginsJSONArray[index].toString())["data"].toString()
479-
val login = mapper.readValue (loginAsJSONObject, IOUtilities.Login::class.java)
480-
logins.add(login)
481-
}
482452

483-
for (index in 0 until notesJSONArray.length()) {
484-
val noteAsJSONObject = JSONObject(notesJSONArray[index].toString())["data"].toString()
485-
val note = mapper.readValue (noteAsJSONObject, IOUtilities.Note::class.java)
486-
notes.add(note)
487-
}
488-
489-
for (index in 0 until cardsJSONArray.length()) {
490-
val cardAsJSONObject = JSONObject(cardsJSONArray[index].toString())["data"].toString()
491-
val card = mapper.readValue (cardAsJSONObject, IOUtilities.Card::class.java)
492-
cards.add(card)
493-
}
494-
495-
for (index in 0 until tagsJSONArray.length()) {
496-
val tagAsJSONObject = JSONObject(tagsJSONArray[index].toString())["data"].toString()
497-
val tag = mapper.readValue (tagAsJSONObject, IOUtilities.Tag::class.java)
498-
tags.add(tag)
499-
}
500-
501-
vault = IOUtilities.Vault (
502-
version = keyspaceStatus().apiVersion,
503-
tag = tags,
504-
login = logins,
505-
note = notes,
506-
card = cards,
507-
)
508-
509-
statusCode = RESPONSE_SUCCESS
453+
val vaultData = synchronousGetRequestWithAuthorizationHeader (
454+
vault_items_endpoint,
455+
signedToken = signedToken
456+
)
510457

511-
} catch (emptyVault: JSONException) {
512-
//Log.d("KeyspaceVAULTSYNC", "Server returned empty vault! Received vaultData: ${response.toString()}")
513-
//Log.e("KeyspaceVAULTSYNC", emptyVault.stackTraceToString())
514-
statusCode = RESPONSE_VAULT_DOES_NOT_EXIST
515-
vault = freshVault
516-
return Pair (vault, statusCode)
458+
val TYPE_LOGIN = "login"
459+
val TYPE_NOTE = "note"
460+
val TYPE_CARD = "card"
461+
val TYPE_TAG = "tag"
462+
463+
var vaultItemList = mutableListOf<String>()
464+
if (vaultData.toString().contains("corrupt")) throw InvalidObjectException(RESPONSE_VAULT_CORRUPT)
465+
val data = JSONObject(vaultData?.get("data").toString())
466+
467+
var loginsJSONArray = JSONArray()
468+
var notesJSONArray = JSONArray()
469+
var cardsJSONArray = JSONArray()
470+
var tagsJSONArray = JSONArray()
471+
472+
try { loginsJSONArray = data.getJSONArray(TYPE_LOGIN) } catch (_: JSONException) {}
473+
try { notesJSONArray = data.getJSONArray(TYPE_NOTE) } catch (_: JSONException) {}
474+
try { cardsJSONArray = data.getJSONArray(TYPE_CARD) } catch (_: JSONException) {}
475+
try { tagsJSONArray = data.getJSONArray(TYPE_TAG) } catch (_: JSONException) {}
476+
477+
val logins: MutableList<IOUtilities.Login> = mutableListOf()
478+
val notes: MutableList<IOUtilities.Note> = mutableListOf()
479+
val cards: MutableList<IOUtilities.Card> = mutableListOf()
480+
val tags: MutableList<IOUtilities.Tag> = mutableListOf()
481+
482+
for (index in 0 until loginsJSONArray.length()) {
483+
val loginAsJSONObject = JSONObject(loginsJSONArray[index].toString())["data"].toString()
484+
val login = mapper.readValue (loginAsJSONObject, IOUtilities.Login::class.java)
485+
logins.add(login)
486+
}
517487

518-
} catch (corruptVault: InvalidObjectException) {
519-
//Log.d("KeyspaceVAULTSYNC", "Server returned corrupt vault! Received vaultData: ${response.toString()}")
520-
//Log.e("KeyspaceVAULTSYNC", corruptVault.stackTraceToString())
521-
statusCode = RESPONSE_VAULT_CORRUPT
522-
vault = freshVault
523-
return Pair (vault, statusCode)
488+
for (index in 0 until notesJSONArray.length()) {
489+
val noteAsJSONObject = JSONObject(notesJSONArray[index].toString())["data"].toString()
490+
val note = mapper.readValue (noteAsJSONObject, IOUtilities.Note::class.java)
491+
notes.add(note)
492+
}
524493

525-
} catch (noInternet: NetworkError) {
526-
vault = null
527-
statusCode = NETWORK_ERROR
528-
return Pair (vault, statusCode)
494+
for (index in 0 until cardsJSONArray.length()) {
495+
val cardAsJSONObject = JSONObject(cardsJSONArray[index].toString())["data"].toString()
496+
val card = mapper.readValue (cardAsJSONObject, IOUtilities.Card::class.java)
497+
cards.add(card)
498+
}
529499

500+
for (index in 0 until tagsJSONArray.length()) {
501+
val tagAsJSONObject = JSONObject(tagsJSONArray[index].toString())["data"].toString()
502+
val tag = mapper.readValue (tagAsJSONObject, IOUtilities.Tag::class.java)
503+
tags.add(tag)
530504
}
531505

532-
return Pair (vault, statusCode)
506+
vault = IOUtilities.Vault (
507+
version = keyspaceStatus().apiVersion,
508+
tag = tags,
509+
login = logins,
510+
note = notes,
511+
card = cards,
512+
)
513+
514+
return vault
533515

534516
}
535517

@@ -629,6 +611,7 @@ class NetworkUtilities (
629611
val email: String,
630612
)
631613

614+
class AccountExistsException : Exception()
632615
suspend fun sendSignupRequest (signupParameters: SignupParameters): SignupResponse? {
633616
var signupResponse: SignupResponse? = null
634617

@@ -642,10 +625,14 @@ class NetworkUtilities (
642625
Map::class.java
643626
) as Map<String, String>
644627

645-
signupResponse = mapper.readValue (
646-
synchronousJsonPostRequest(signup_endpoint, signupParametersAsMap)!!.toString(),
647-
SignupResponse::class.java
648-
)
628+
try {
629+
signupResponse = mapper.readValue (
630+
synchronousJsonPostRequest(signup_endpoint, signupParametersAsMap)!!.toString(),
631+
SignupResponse::class.java
632+
)
633+
} catch (_: MissingKotlinParameterException) {
634+
throw AccountExistsException()
635+
}
649636

650637
return signupResponse
651638
}

0 commit comments

Comments
 (0)