add PIN/PUK/pairing validation/confirmation
This commit is contained in:
parent
04398f58d7
commit
52cdd38147
|
@ -3,7 +3,7 @@
|
||||||
**NOTE**: _This app is a prototype. While it seems to work reasonably well and stable, the UI has not received any thought yet.
|
**NOTE**: _This app is a prototype. While it seems to work reasonably well and stable, the UI has not received any thought yet.
|
||||||
It is fine to use but keep in mind that there isn't much error reporting, no progress indicators and some screens are crammed with info_
|
It is fine to use but keep in mind that there isn't much error reporting, no progress indicators and some screens are crammed with info_
|
||||||
|
|
||||||
Keycard Connect's main function is to enable using the Keycard with dApps outside of a web3 browser using WalletConnect. The dApp must of course support WalletConnect for this to work. Additionally, this app is a little toolbox for Keycardm allowing things like changing PIN, initializing cards, changing seed etc.
|
Keycard Connect's main function is to enable using the Keycard with dApps outside of a web3 browser using WalletConnect. The dApp must of course support WalletConnect for this to work. Additionally, this app is a little toolbox for Keycard, allowing things like changing PIN, initializing cards, changing seed etc.
|
||||||
|
|
||||||
## What works
|
## What works
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
package im.status.keycard.connect.data
|
||||||
|
|
||||||
|
fun isValidPIN(pin: String) : Boolean = pin.length == 6 && pin.all { it.isDigit() }
|
||||||
|
fun isValidPUK(puk: String) : Boolean = puk.length == 12 && puk.all { it.isDigit() }
|
|
@ -18,7 +18,7 @@ class EthereumRPC(endpointURL: String) {
|
||||||
init {
|
init {
|
||||||
val moshi = Moshi.Builder().build()
|
val moshi = Moshi.Builder().build()
|
||||||
val type: Type = Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java)
|
val type: Type = Types.newParameterizedType(Map::class.java, String::class.java, Any::class.java)
|
||||||
ethplorerJSONAdapter = moshi.adapter<Map<String, Any>>(type)
|
ethplorerJSONAdapter = moshi.adapter(type)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun changeEndpoint(endpointURL: String) {
|
fun changeEndpoint(endpointURL: String) {
|
||||||
|
|
|
@ -2,18 +2,25 @@ package im.status.keycard.connect.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.Button
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.widget.doAfterTextChanged
|
||||||
import im.status.keycard.connect.R
|
import im.status.keycard.connect.R
|
||||||
import im.status.keycard.connect.Registry
|
import im.status.keycard.connect.Registry
|
||||||
import im.status.keycard.connect.card.ChangePINCommand
|
import im.status.keycard.connect.card.ChangePINCommand
|
||||||
import im.status.keycard.connect.card.scriptWithAuthentication
|
import im.status.keycard.connect.card.scriptWithAuthentication
|
||||||
|
import im.status.keycard.connect.data.isValidPIN
|
||||||
|
|
||||||
class ChangePINActivity : AppCompatActivity() {
|
class ChangePINActivity : AppCompatActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
//TODO: pin validation and confirmation
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_change_pin)
|
setContentView(R.layout.activity_change_pin)
|
||||||
|
|
||||||
|
val pinText = findViewById<EditText>(R.id.newPINText)
|
||||||
|
val pinConfirmation = findViewById<EditText>(R.id.pinConfirmation)
|
||||||
|
pinText.doAfterTextChanged { validatePIN() }
|
||||||
|
pinConfirmation.doAfterTextChanged { validatePIN() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ok(@Suppress("UNUSED_PARAMETER") view: View) {
|
fun ok(@Suppress("UNUSED_PARAMETER") view: View) {
|
||||||
|
@ -26,4 +33,11 @@ class ChangePINActivity : AppCompatActivity() {
|
||||||
fun cancel(@Suppress("UNUSED_PARAMETER") view: View) {
|
fun cancel(@Suppress("UNUSED_PARAMETER") view: View) {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun validatePIN() {
|
||||||
|
val pinText = findViewById<EditText>(R.id.newPINText).text.toString()
|
||||||
|
val pinConfirmation = findViewById<EditText>(R.id.pinConfirmation).text.toString()
|
||||||
|
val button = findViewById<Button>(R.id.okButton)
|
||||||
|
button.isEnabled = (pinText == pinConfirmation) && isValidPIN(pinText)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,25 @@ package im.status.keycard.connect.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.Button
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.widget.doAfterTextChanged
|
||||||
import im.status.keycard.connect.R
|
import im.status.keycard.connect.R
|
||||||
import im.status.keycard.connect.Registry
|
import im.status.keycard.connect.Registry
|
||||||
import im.status.keycard.connect.card.ChangePUKCommand
|
import im.status.keycard.connect.card.ChangePUKCommand
|
||||||
import im.status.keycard.connect.card.scriptWithAuthentication
|
import im.status.keycard.connect.card.scriptWithAuthentication
|
||||||
|
import im.status.keycard.connect.data.isValidPUK
|
||||||
|
|
||||||
class ChangePUKActivity : AppCompatActivity() {
|
class ChangePUKActivity : AppCompatActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
//TODO: puk validation and confirmation
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_change_puk)
|
setContentView(R.layout.activity_change_puk)
|
||||||
|
|
||||||
|
val pukText = findViewById<EditText>(R.id.newPUKText)
|
||||||
|
val pukConfirmation = findViewById<EditText>(R.id.pukConfirmation)
|
||||||
|
pukText.doAfterTextChanged { validatePUK() }
|
||||||
|
pukConfirmation.doAfterTextChanged { validatePUK() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ok(@Suppress("UNUSED_PARAMETER") view: View) {
|
fun ok(@Suppress("UNUSED_PARAMETER") view: View) {
|
||||||
|
@ -26,4 +33,11 @@ class ChangePUKActivity : AppCompatActivity() {
|
||||||
fun cancel(@Suppress("UNUSED_PARAMETER") view: View) {
|
fun cancel(@Suppress("UNUSED_PARAMETER") view: View) {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun validatePUK() {
|
||||||
|
val pukText = findViewById<EditText>(R.id.newPUKText).text.toString()
|
||||||
|
val pukConfirmation = findViewById<EditText>(R.id.pukConfirmation).text.toString()
|
||||||
|
val button = findViewById<Button>(R.id.okButton)
|
||||||
|
button.isEnabled = (pukText == pukConfirmation) && isValidPUK(pukText)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,18 +2,25 @@ package im.status.keycard.connect.ui
|
||||||
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
|
import android.widget.Button
|
||||||
import android.widget.EditText
|
import android.widget.EditText
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.core.widget.doAfterTextChanged
|
||||||
import im.status.keycard.connect.R
|
import im.status.keycard.connect.R
|
||||||
import im.status.keycard.connect.Registry
|
import im.status.keycard.connect.Registry
|
||||||
import im.status.keycard.connect.card.ChangePairingPasswordCommand
|
import im.status.keycard.connect.card.ChangePairingPasswordCommand
|
||||||
import im.status.keycard.connect.card.scriptWithAuthentication
|
import im.status.keycard.connect.card.scriptWithAuthentication
|
||||||
|
import im.status.keycard.connect.data.isValidPUK
|
||||||
|
|
||||||
class ChangePairingPasswordActivity : AppCompatActivity() {
|
class ChangePairingPasswordActivity : AppCompatActivity() {
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
//TODO: pairing password confirmation
|
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
setContentView(R.layout.activity_change_pairing_password)
|
setContentView(R.layout.activity_change_pairing_password)
|
||||||
|
|
||||||
|
val pairingPasswordText = findViewById<EditText>(R.id.newPairingPasswordText)
|
||||||
|
val pairingPasswordConfirmation = findViewById<EditText>(R.id.pairingPasswordConfirmation)
|
||||||
|
pairingPasswordText.doAfterTextChanged { validatePairingPassword() }
|
||||||
|
pairingPasswordConfirmation.doAfterTextChanged { validatePairingPassword() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ok(@Suppress("UNUSED_PARAMETER") view: View) {
|
fun ok(@Suppress("UNUSED_PARAMETER") view: View) {
|
||||||
|
@ -26,4 +33,11 @@ class ChangePairingPasswordActivity : AppCompatActivity() {
|
||||||
fun cancel(@Suppress("UNUSED_PARAMETER") view: View) {
|
fun cancel(@Suppress("UNUSED_PARAMETER") view: View) {
|
||||||
finish()
|
finish()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun validatePairingPassword() {
|
||||||
|
val pairingPasswordText = findViewById<EditText>(R.id.newPairingPasswordText).text.toString()
|
||||||
|
val pairingPasswordConfirmation = findViewById<EditText>(R.id.pairingPasswordConfirmation).text.toString()
|
||||||
|
val button = findViewById<Button>(R.id.okButton)
|
||||||
|
button.isEnabled = (pairingPasswordText == pairingPasswordConfirmation) && pairingPasswordText.isNotEmpty()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="88dp"
|
android:layout_marginEnd="88dp"
|
||||||
|
android:enabled="false"
|
||||||
android:onClick="ok"
|
android:onClick="ok"
|
||||||
android:text="@android:string/ok"
|
android:text="@android:string/ok"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -32,12 +33,12 @@
|
||||||
android:id="@+id/cancelButton"
|
android:id="@+id/cancelButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="68dp"
|
android:layout_marginStart="64dp"
|
||||||
android:layout_marginTop="76dp"
|
android:layout_marginTop="88dp"
|
||||||
android:onClick="cancel"
|
android:onClick="cancel"
|
||||||
android:text="@android:string/cancel"
|
android:text="@android:string/cancel"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/newPairingPasswordText" />
|
app:layout_constraintTop_toBottomOf="@+id/pairingPasswordConfirmation" />
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/newPairingPasswordText"
|
android:id="@+id/newPairingPasswordText"
|
||||||
|
@ -50,4 +51,17 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/newPairingPasswordPrompt"
|
app:layout_constraintTop_toBottomOf="@+id/newPairingPasswordPrompt"
|
||||||
tools:text="password" />
|
tools:text="password" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/pairingPasswordConfirmation"
|
||||||
|
android:layout_width="328dp"
|
||||||
|
android:layout_height="46dp"
|
||||||
|
android:layout_marginTop="68dp"
|
||||||
|
android:ems="10"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.493"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/newPairingPasswordText"
|
||||||
|
tools:text="password" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -22,6 +22,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="88dp"
|
android:layout_marginEnd="88dp"
|
||||||
|
android:enabled="false"
|
||||||
android:onClick="ok"
|
android:onClick="ok"
|
||||||
android:text="@android:string/ok"
|
android:text="@android:string/ok"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -31,12 +32,12 @@
|
||||||
android:id="@+id/cancelButton"
|
android:id="@+id/cancelButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="68dp"
|
android:layout_marginTop="68dp"
|
||||||
android:layout_marginTop="76dp"
|
|
||||||
android:onClick="cancel"
|
android:onClick="cancel"
|
||||||
android:text="@android:string/cancel"
|
android:text="@android:string/cancel"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/okButton"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/newPINText" />
|
app:layout_constraintTop_toBottomOf="@+id/pinConfirmation" />
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/newPINText"
|
android:id="@+id/newPINText"
|
||||||
|
@ -49,4 +50,16 @@
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/newPinPrompt"
|
app:layout_constraintTop_toBottomOf="@+id/newPinPrompt"
|
||||||
tools:text="123456" />
|
tools:text="123456" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/pinConfirmation"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="64dp"
|
||||||
|
android:ems="10"
|
||||||
|
android:inputType="numberPassword"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/newPINText"
|
||||||
|
tools:text="123456" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -22,6 +22,7 @@
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginEnd="88dp"
|
android:layout_marginEnd="88dp"
|
||||||
|
android:enabled="false"
|
||||||
android:onClick="ok"
|
android:onClick="ok"
|
||||||
android:text="@android:string/ok"
|
android:text="@android:string/ok"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
@ -31,12 +32,13 @@
|
||||||
android:id="@+id/cancelButton"
|
android:id="@+id/cancelButton"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="68dp"
|
android:layout_marginTop="84dp"
|
||||||
android:layout_marginTop="76dp"
|
|
||||||
android:onClick="cancel"
|
android:onClick="cancel"
|
||||||
android:text="@android:string/cancel"
|
android:text="@android:string/cancel"
|
||||||
|
app:layout_constraintEnd_toStartOf="@+id/okButton"
|
||||||
|
app:layout_constraintHorizontal_bias="0.557"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/newPUKText" />
|
app:layout_constraintTop_toBottomOf="@+id/pukConfirmation" />
|
||||||
|
|
||||||
<EditText
|
<EditText
|
||||||
android:id="@+id/newPUKText"
|
android:id="@+id/newPUKText"
|
||||||
|
@ -48,5 +50,18 @@
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/newPukPrompt"
|
app:layout_constraintTop_toBottomOf="@+id/newPukPrompt"
|
||||||
tools:text="123456" />
|
tools:text="123456123456" />
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/pukConfirmation"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="60dp"
|
||||||
|
android:ems="10"
|
||||||
|
android:inputType="numberPassword"
|
||||||
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHorizontal_bias="0.502"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
|
app:layout_constraintTop_toBottomOf="@+id/newPUKText"
|
||||||
|
tools:text="123456123456" />
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -10,7 +10,7 @@ buildscript {
|
||||||
|
|
||||||
}
|
}
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:4.0.2'
|
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
|
||||||
// NOTE: Do not place your application dependencies here; they belong
|
// NOTE: Do not place your application dependencies here; they belong
|
||||||
// in the individual module build.gradle files
|
// in the individual module build.gradle files
|
||||||
|
|
Loading…
Reference in New Issue