mirror of
https://github.com/TanelOrumaa/Estonian-ID-card-mobile-authenticator-POC.git
synced 2025-12-04 21:05:13 +02:00
Merged main to branch to support DeepLink
This commit is contained in:
@@ -67,4 +67,7 @@ dependencies {
|
||||
'org.bouncycastle:bcprov-jdk15on:1.60',
|
||||
'io.jsonwebtoken:jjwt-gson:0.11.2'
|
||||
|
||||
// Retrofit + Moshi Converter
|
||||
implementation 'com.squareup.retrofit2:converter-moshi:2.9.0'
|
||||
implementation 'com.squareup.moshi:moshi-kotlin:1.9.3'
|
||||
}
|
||||
@@ -19,6 +19,13 @@
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<!-- for launching the app with deep links -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:scheme="authapp" android:host="start" android:path="/" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package com.tarkvaraprojekt.mobileauthapp
|
||||
|
||||
import android.app.Activity
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.nfc.NfcAdapter
|
||||
import android.nfc.tech.IsoDep
|
||||
import android.os.Bundle
|
||||
@@ -10,15 +9,16 @@ import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import com.tarkvaraprojekt.mobileauthapp.NFC.Comms
|
||||
import com.tarkvaraprojekt.mobileauthapp.auth.Authenticator
|
||||
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentAuthBinding
|
||||
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
||||
import java.lang.Exception
|
||||
import kotlin.concurrent.thread
|
||||
|
||||
/**
|
||||
* Fragment that asks the user to detect the ID card with mobile NFC chip.
|
||||
@@ -31,6 +31,8 @@ class AuthFragment : Fragment() {
|
||||
|
||||
private var binding: FragmentAuthBinding? = null
|
||||
|
||||
private val args: CanFragmentArgs by navArgs()
|
||||
|
||||
private lateinit var timer: CountDownTimer
|
||||
|
||||
private var timeRemaining: Int = 90
|
||||
@@ -69,51 +71,66 @@ class AuthFragment : Fragment() {
|
||||
}
|
||||
|
||||
private fun getInfoFromIdCard(adapter: NfcAdapter) {
|
||||
adapter.enableReaderMode(activity, { tag ->
|
||||
timer.cancel()
|
||||
requireActivity().runOnUiThread {
|
||||
binding!!.timeCounter.text = getString(R.string.card_detected)
|
||||
}
|
||||
val card = IsoDep.get(tag)
|
||||
card.timeout = 32768
|
||||
card.use {
|
||||
try {
|
||||
val comms = Comms(it, viewModel.userCan)
|
||||
val response = comms.readPersonalData(byteArrayOf(1, 2, 6, 3, 4, 8))
|
||||
viewModel.setUserFirstName(response[1])
|
||||
viewModel.setUserLastName(response[0])
|
||||
viewModel.setUserIdentificationNumber(response[2])
|
||||
viewModel.setGender(response[3])
|
||||
viewModel.setCitizenship(response[4])
|
||||
viewModel.setExpiration(response[5])
|
||||
requireActivity().runOnUiThread{
|
||||
binding!!.timeCounter.text = getString(R.string.data_read)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
requireActivity().runOnUiThread {
|
||||
binding!!.timeCounter.text = getString(R.string.no_success)
|
||||
}
|
||||
// If the CAN is wrong we will also delete the saved CAN so that the user won't use it again.
|
||||
viewModel.deleteCan(requireContext())
|
||||
// Gives user some time to read the error message
|
||||
Thread.sleep(1000)
|
||||
goToTheStart()
|
||||
} finally {
|
||||
adapter.disableReaderMode(activity)
|
||||
if (args.reading) {
|
||||
adapter.enableReaderMode(activity, { tag ->
|
||||
timer.cancel()
|
||||
requireActivity().runOnUiThread {
|
||||
binding!!.timeCounter.text = getString(R.string.card_detected)
|
||||
}
|
||||
}
|
||||
}, NfcAdapter.FLAG_READER_NFC_A, null)
|
||||
val card = IsoDep.get(tag)
|
||||
card.timeout = 32768
|
||||
card.use {
|
||||
try {
|
||||
val comms = Comms(it, viewModel.userCan)
|
||||
val response = comms.readPersonalData(byteArrayOf(1, 2, 6, 3, 4, 8))
|
||||
viewModel.setUserFirstName(response[1])
|
||||
viewModel.setUserLastName(response[0])
|
||||
viewModel.setUserIdentificationNumber(response[2])
|
||||
viewModel.setGender(response[3])
|
||||
viewModel.setCitizenship(response[4])
|
||||
viewModel.setExpiration(response[5])
|
||||
requireActivity().runOnUiThread {
|
||||
binding!!.timeCounter.text = getString(R.string.data_read)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
requireActivity().runOnUiThread {
|
||||
binding!!.timeCounter.text = getString(R.string.no_success)
|
||||
}
|
||||
// If the CAN is wrong we will also delete the saved CAN so that the user won't use it again.
|
||||
viewModel.deleteCan(requireContext())
|
||||
// Gives user some time to read the error message
|
||||
Thread.sleep(1000)
|
||||
goToTheStart()
|
||||
} finally {
|
||||
adapter.disableReaderMode(activity)
|
||||
}
|
||||
}
|
||||
}, NfcAdapter.FLAG_READER_NFC_A, null)
|
||||
} else { //We want to create a JWT instead of reading the info from the card.
|
||||
goToNextFragment()
|
||||
}
|
||||
}
|
||||
|
||||
private fun goToNextFragment() {
|
||||
timer.cancel()
|
||||
findNavController().navigate(R.id.action_authFragment_to_userFragment)
|
||||
if (args.auth) {
|
||||
val action = AuthFragmentDirections.actionAuthFragmentToResultFragment(mobile = args.mobile)
|
||||
findNavController().navigate(action)
|
||||
} else {
|
||||
findNavController().navigate(R.id.action_authFragment_to_userFragment)
|
||||
}
|
||||
}
|
||||
|
||||
private fun goToTheStart() {
|
||||
viewModel.clearUserInfo()
|
||||
timer.cancel()
|
||||
findNavController().navigate(R.id.action_authFragment_to_homeFragment)
|
||||
if (args.reading) {
|
||||
findNavController().navigate(R.id.action_authFragment_to_homeFragment)
|
||||
} else {
|
||||
val resultIntent = Intent()
|
||||
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent)
|
||||
requireActivity().finish()
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
package com.tarkvaraprojekt.mobileauthapp
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
@@ -65,7 +67,7 @@ class CanFragment : Fragment() {
|
||||
* Takes user to the next fragment, which is PinFragment.
|
||||
*/
|
||||
private fun goToTheNextFragment() {
|
||||
val action = CanFragmentDirections.actionCanFragmentToPinFragment(reading = args.reading)
|
||||
val action = CanFragmentDirections.actionCanFragmentToPinFragment(reading = args.reading, auth = args.auth, mobile = args.mobile)
|
||||
findNavController().navigate(action)
|
||||
}
|
||||
|
||||
@@ -122,8 +124,13 @@ class CanFragment : Fragment() {
|
||||
* not the HomeFragment.
|
||||
*/
|
||||
private fun goToTheStart() {
|
||||
// TODO: Needs special handling when the app is launched with intent. Temporary solution at the moment.
|
||||
if (args.saving) {
|
||||
findNavController().navigate(R.id.action_canFragment_to_settingsFragment)
|
||||
} else if (args.auth) {
|
||||
val resultIntent = Intent()
|
||||
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent)
|
||||
requireActivity().finish()
|
||||
} else {
|
||||
findNavController().navigate(R.id.action_canFragment_to_homeFragment)
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package com.tarkvaraprojekt.mobileauthapp
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
@@ -37,6 +39,14 @@ class HomeFragment : Fragment() {
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
initialChecks()
|
||||
var mobile = false
|
||||
if (requireActivity().intent.data?.getQueryParameter("arg1") != null) {
|
||||
mobile = true
|
||||
}
|
||||
val auth = requireActivity().intent.getBooleanExtra("auth", false)
|
||||
if (auth || mobile){
|
||||
goToTheNextFragment(true, mobile)
|
||||
}
|
||||
binding!!.beginButton.setOnClickListener { goToTheNextFragment() }
|
||||
}
|
||||
|
||||
@@ -52,13 +62,19 @@ class HomeFragment : Fragment() {
|
||||
/**
|
||||
* Starts the process of interacting with the ID card by sending user to the CAN fragment.
|
||||
*/
|
||||
private fun goToTheNextFragment() {
|
||||
private fun goToTheNextFragment(auth: Boolean = false, mobile: Boolean = false) {
|
||||
// Making settings menu inactive
|
||||
(activity as MainActivity).menuAvailable = false
|
||||
// Currently saving is true because the application is not yet integrated with
|
||||
// other applications or websites.
|
||||
val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(reading = true)
|
||||
findNavController().navigate(action)
|
||||
// TODO: Check the navigation action default values. Not everything has to be declared explicitly.
|
||||
if (auth) {
|
||||
val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(reading = false, auth = true, mobile = mobile)
|
||||
findNavController().navigate(action)
|
||||
} else {
|
||||
val action = HomeFragmentDirections.actionHomeFragmentToCanFragment(reading = true, auth = false, mobile = mobile)
|
||||
findNavController().navigate(action)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package com.tarkvaraprojekt.mobileauthapp
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentPin2Binding
|
||||
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
||||
|
||||
/**
|
||||
* Fragment that deals with asking PIN 2 from the user. Basically the same as PIN 1 fragment.
|
||||
*/
|
||||
class Pin2Fragment : Fragment() {
|
||||
|
||||
private val viewModel: SmartCardViewModel by activityViewModels()
|
||||
|
||||
private var binding: FragmentPin2Binding? = null
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
binding = FragmentPin2Binding.inflate(inflater, container, false)
|
||||
return binding!!.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding!!.nextButton.setOnClickListener {
|
||||
checkPin2Length()
|
||||
}
|
||||
binding!!.cancelButton.setOnClickListener {
|
||||
cancel()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the length of the entered PIN 2 is in range 5..12 and if it is
|
||||
* then it is saved to the viewModel.
|
||||
*/
|
||||
private fun checkPin2Length() {
|
||||
val enteredPin2 = binding!!.pin2EditText.editText?.text.toString()
|
||||
if (enteredPin2.length in 5..12) {
|
||||
viewModel.setUserPin2(enteredPin2)
|
||||
} else {
|
||||
Toast.makeText(requireContext(), getString(R.string.length_pin2), Toast.LENGTH_SHORT)
|
||||
.show()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Authentication process is cancelled when cancel button is clicked and the application
|
||||
* will be closed.
|
||||
*/
|
||||
private fun cancel() {
|
||||
val resultIntent = Intent()
|
||||
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent)
|
||||
requireActivity().finish()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
binding = null
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,11 +1,13 @@
|
||||
package com.tarkvaraprojekt.mobileauthapp
|
||||
|
||||
import android.app.AlertDialog
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Toast
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.findNavController
|
||||
@@ -68,7 +70,8 @@ class PinFragment : Fragment() {
|
||||
* Takes user to the next fragment, which is AuthFragment.
|
||||
*/
|
||||
private fun goToTheNextFragment() {
|
||||
findNavController().navigate(R.id.action_pinFragment_to_authFragment)
|
||||
val action = PinFragmentDirections.actionPinFragmentToAuthFragment(reading = args.reading, auth = args.auth, mobile = args.mobile)
|
||||
findNavController().navigate(action)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -124,10 +127,13 @@ class PinFragment : Fragment() {
|
||||
*/
|
||||
private fun goToTheStart() {
|
||||
if (args.saving) {
|
||||
findNavController().navigate(R.id.action_pinFragment_to_settingsFragment)
|
||||
findNavController().navigate(R.id.action_canFragment_to_settingsFragment)
|
||||
} else if (args.auth) {
|
||||
val resultIntent = Intent()
|
||||
requireActivity().setResult(AppCompatActivity.RESULT_CANCELED, resultIntent)
|
||||
requireActivity().finish()
|
||||
} else {
|
||||
viewModel.clearUserInfo()
|
||||
findNavController().navigate(R.id.action_pinFragment_to_homeFragment)
|
||||
findNavController().navigate(R.id.action_canFragment_to_homeFragment)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
package com.tarkvaraprojekt.mobileauthapp
|
||||
|
||||
import android.content.Intent
|
||||
import android.os.Bundle
|
||||
import android.util.Log
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.fragment.app.activityViewModels
|
||||
import androidx.navigation.fragment.navArgs
|
||||
import com.tarkvaraprojekt.mobileauthapp.databinding.FragmentResultBinding
|
||||
import com.tarkvaraprojekt.mobileauthapp.model.SmartCardViewModel
|
||||
|
||||
/**
|
||||
* ResultFragment is used to create a JWT and to send response to the website/application
|
||||
* that launched the MobileAuthApp. If the mobile auth app was started by a website
|
||||
* the result is sent to a server with a POST request.
|
||||
*/
|
||||
class ResultFragment : Fragment() {
|
||||
|
||||
private val viewModel: SmartCardViewModel by activityViewModels()
|
||||
|
||||
private var binding: FragmentResultBinding? = null
|
||||
|
||||
private val args: CanFragmentArgs by navArgs()
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
binding = FragmentResultBinding.inflate(inflater, container, false)
|
||||
return binding!!.root
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
super.onViewCreated(view, savedInstanceState)
|
||||
binding!!.resultBackButton.setOnClickListener {
|
||||
if (!args.mobile) {
|
||||
createResponse()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createResponse() {
|
||||
val resultIntent = Intent()
|
||||
requireActivity().setResult(AppCompatActivity.RESULT_OK, resultIntent)
|
||||
requireActivity().finish()
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
binding = null
|
||||
}
|
||||
|
||||
}
|
||||
@@ -11,6 +11,9 @@ class SmartCardViewModel: ViewModel() {
|
||||
private var _userPin: String = ""
|
||||
val userPin get() = _userPin
|
||||
|
||||
private var _userPin2: String = ""
|
||||
val userPin2 get() = _userPin2
|
||||
|
||||
private var _userCan: String = ""
|
||||
val userCan get() = _userCan
|
||||
|
||||
@@ -34,6 +37,7 @@ class SmartCardViewModel: ViewModel() {
|
||||
|
||||
fun clearUserInfo() {
|
||||
_userPin = ""
|
||||
_userPin2 = ""
|
||||
_userCan = ""
|
||||
_userFirstName = ""
|
||||
_userLastName = ""
|
||||
@@ -47,6 +51,10 @@ class SmartCardViewModel: ViewModel() {
|
||||
_userPin = newUserPin
|
||||
}
|
||||
|
||||
fun setUserPin2(newUserPin2: String) {
|
||||
_userPin2 = newUserPin2
|
||||
}
|
||||
|
||||
fun setUserCan(newUserCan: String) {
|
||||
_userCan = newUserCan
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
package com.tarkvaraprojekt.mobileauthapp.network
|
||||
|
||||
/**
|
||||
* Placeholder ResponseItem.
|
||||
*/
|
||||
data class ResponseItem (
|
||||
val data1: Int,
|
||||
val data2: Int,
|
||||
)
|
||||
@@ -0,0 +1,37 @@
|
||||
package com.tarkvaraprojekt.mobileauthapp.network
|
||||
|
||||
import com.squareup.moshi.Moshi
|
||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||
import retrofit2.Response
|
||||
import retrofit2.Retrofit
|
||||
import retrofit2.converter.moshi.MoshiConverterFactory
|
||||
import retrofit2.http.Body
|
||||
import retrofit2.http.GET
|
||||
import retrofit2.http.Headers
|
||||
import retrofit2.http.POST
|
||||
|
||||
/**
|
||||
* Class for making HTTP requests
|
||||
* Based on https://developer.android.com/courses/pathways/android-basics-kotlin-unit-4-pathway-2
|
||||
*/
|
||||
private const val BASE_URL =
|
||||
"add-endpoint-url-here"
|
||||
|
||||
private val moshi = Moshi.Builder().add(KotlinJsonAdapterFactory()).build()
|
||||
private val retrofit = Retrofit.Builder().addConverterFactory(MoshiConverterFactory.create(moshi))
|
||||
.baseUrl(BASE_URL).build()
|
||||
|
||||
interface TokenApiService {
|
||||
@GET("something")
|
||||
suspend fun getData(): ResponseItem
|
||||
|
||||
@Headers("Content-Type: application/json")
|
||||
@POST("posts")
|
||||
suspend fun addData(@Body data: ResponseItem): Response<ResponseItem>
|
||||
}
|
||||
|
||||
object TokenApi {
|
||||
val retrofitService : TokenApiService by lazy {
|
||||
retrofit.create(TokenApiService::class.java)
|
||||
}
|
||||
}
|
||||
84
MobileAuthApp/app/src/main/res/layout/fragment_pin2.xml
Normal file
84
MobileAuthApp/app/src/main/res/layout/fragment_pin2.xml
Normal file
@@ -0,0 +1,84 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="24dp"
|
||||
tools:context=".Pin2Fragment">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/card_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:strokeWidth="1dp"
|
||||
app:strokeColor="@color/stroke_color"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:padding="20dp">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/pin2_fragment_text"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="6dp"
|
||||
android:text="@string/pin2_fragment" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/pin2_edit_text"
|
||||
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="6dp"
|
||||
android:hint="@string/enter_pin2"
|
||||
app:counterEnabled="true"
|
||||
app:counterMaxLength="12"
|
||||
app:endIconMode="password_toggle"
|
||||
app:errorEnabled="true"
|
||||
app:helperText="@string/example_pin2"
|
||||
app:helperTextEnabled="true"
|
||||
app:startIconDrawable="@drawable/can_logo">
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:inputType="numberPassword"
|
||||
android:textSize="14sp" />
|
||||
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
<Button
|
||||
android:id="@+id/next_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:text="@string/next_text"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@id/cancel_button"
|
||||
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/cancel_button"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="24dp"
|
||||
android:text="@string/cancel_text"
|
||||
android:textSize="15sp"
|
||||
app:layout_constraintEnd_toStartOf="@id/next_button"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/card_view" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
59
MobileAuthApp/app/src/main/res/layout/fragment_result.xml
Normal file
59
MobileAuthApp/app/src/main/res/layout/fragment_result.xml
Normal file
@@ -0,0 +1,59 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:padding="24dp"
|
||||
tools:context=".ResultFragment">
|
||||
|
||||
<com.google.android.material.card.MaterialCardView
|
||||
android:id="@+id/can_status"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="12dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:strokeWidth="1dp"
|
||||
app:strokeColor="@color/stroke_color"
|
||||
app:cardElevation="0dp">
|
||||
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/result_text"
|
||||
android:text="@string/result_text"
|
||||
android:textSize="20sp"
|
||||
android:padding="12dp"
|
||||
android:layout_marginVertical="6dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/result_info_text"
|
||||
android:text="@string/result_info"
|
||||
android:padding="12dp"
|
||||
android:textSize="16sp"
|
||||
android:layout_marginVertical="6dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/result_back_button"
|
||||
android:text="@string/return_text"
|
||||
android:layout_marginHorizontal="12dp"
|
||||
android:layout_marginVertical="6dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</com.google.android.material.card.MaterialCardView>
|
||||
|
||||
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -46,6 +46,14 @@
|
||||
android:name="reading"
|
||||
app:argType="boolean"
|
||||
android:defaultValue="false" />
|
||||
<argument
|
||||
android:name="auth"
|
||||
app:argType="boolean"
|
||||
android:defaultValue="false" />
|
||||
<argument
|
||||
android:name="mobile"
|
||||
app:argType="boolean"
|
||||
android:defaultValue="false" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/canFragment"
|
||||
@@ -74,6 +82,14 @@
|
||||
android:name="reading"
|
||||
app:argType="boolean"
|
||||
android:defaultValue="false" />
|
||||
<argument
|
||||
android:name="auth"
|
||||
app:argType="boolean"
|
||||
android:defaultValue="false" />
|
||||
<argument
|
||||
android:name="mobile"
|
||||
app:argType="boolean"
|
||||
android:defaultValue="false" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/authFragment"
|
||||
@@ -89,6 +105,22 @@
|
||||
app:destination="@id/homeFragment"
|
||||
app:popUpTo="@id/homeFragment"
|
||||
app:popUpToInclusive="true" />
|
||||
<action
|
||||
android:id="@+id/action_authFragment_to_resultFragment"
|
||||
app:destination="@id/resultFragment"
|
||||
app:popUpTo="@id/homeFragment" />
|
||||
<argument
|
||||
android:name="auth"
|
||||
app:argType="boolean"
|
||||
android:defaultValue="false" />
|
||||
<argument
|
||||
android:name="reading"
|
||||
app:argType="boolean"
|
||||
android:defaultValue="false" />
|
||||
<argument
|
||||
android:name="mobile"
|
||||
app:argType="boolean"
|
||||
android:defaultValue="false" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/userFragment"
|
||||
@@ -118,4 +150,14 @@
|
||||
app:popUpTo="@id/homeFragment"
|
||||
app:popUpToInclusive="true" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/resultFragment"
|
||||
android:name="com.tarkvaraprojekt.mobileauthapp.ResultFragment"
|
||||
android:label="fragment_result"
|
||||
tools:layout="@layout/fragment_result" >
|
||||
<argument
|
||||
android:name="mobile"
|
||||
app:argType="boolean"
|
||||
android:defaultValue="false" />
|
||||
</fragment>
|
||||
</navigation>
|
||||
@@ -5,64 +5,74 @@
|
||||
<string name="home_fragment">Work in progress</string>
|
||||
|
||||
<!-- string resources for HomeFragment -->
|
||||
<string name="pin_status_saved">PIN 1 on salvestatud</string>
|
||||
<string name="pin_status_negative">PIN 1 ei ole salvestatud</string>
|
||||
<string name="can_status_saved">CAN on salvestatud</string>
|
||||
<string name="can_status_negative">CAN ei ole salvestatud</string>
|
||||
<string name="pin_status_saved">PIN 1 saved</string>
|
||||
<string name="pin_status_negative">PIN 1 not saved</string>
|
||||
<string name="can_status_saved">CAN saved</string>
|
||||
<string name="can_status_negative">CAN not saved</string>
|
||||
|
||||
<string name="begin_text">LOE ID KAARTI</string>
|
||||
<string name="next_text">EDASI</string>
|
||||
<string name="cancel_text">KATKESTA</string>
|
||||
<string name="save_text">SALVESTA</string>
|
||||
<string name="deny_text">EI</string>
|
||||
<string name="return_text">TAGASI</string>
|
||||
<string name="begin_text">READ ID CARD</string>
|
||||
<string name="next_text">NEXT</string>
|
||||
<string name="cancel_text">CANCEL</string>
|
||||
<string name="save_text">SAVE</string>
|
||||
<string name="deny_text">NO</string>
|
||||
<string name="return_text">BACK</string>
|
||||
|
||||
<!-- string resources for PinFragment -->
|
||||
<string name="pin_fragment">Palun sisesta PIN 1</string>
|
||||
<string name="pin_fragment">Please enter PIN 1</string>
|
||||
<string name="enter_pin">PIN 1</string>
|
||||
<string name="example_pin">Näide. 1234</string>
|
||||
<string name="length_pin">PIN 1 lubatud pikkus on 4..12</string>
|
||||
<string name="pin_save_request">Praegu ei ole rakenduses PIN 1 salvestatud. Kas sa soovid sisestatud PIN 1-te salvestada? Sellisel juhul sisestatakse see järgmisel korral automaatselt. Salvestatud PIN 1-te saab alati menüüs muuta ja kustutada.</string>
|
||||
<string name="save_pin_title">Salvesta PIN 1</string>
|
||||
<string name="example_pin">Example. 1234</string>
|
||||
<string name="length_pin">Allowed length for PIN 1 is 4..12</string>
|
||||
<string name="pin_save_request">PIN 1 is currently not saved. Do you wish to save the entered PIN 1? Saved PIN 1 will be entered automatically in the future. Saved PIN 1 can be changed and deleted in the settings menu.</string>
|
||||
<string name="save_pin_title">Save PIN 1</string>
|
||||
|
||||
<!-- string resources for Pin2Fragment -->
|
||||
<string name="pin2_fragment">Please enter PIN 2</string>
|
||||
<string name="enter_pin2">PIN 2</string>
|
||||
<string name="example_pin2">Example. 123456</string>
|
||||
<string name="length_pin2">Allowed length for PIN 2 is 5..12</string>
|
||||
|
||||
<!-- string resources for CanFragment -->
|
||||
<string name="example_can">Näide. 123456</string>
|
||||
<string name="example_can">Example. 123456</string>
|
||||
<string name="text_can">CAN</string>
|
||||
<string name="enter_can">Sisesta ID kaardi CAN (Card Access Number)</string>
|
||||
<string name="length_can">CANi pikkus on vale</string>
|
||||
<string name="card_detected">Kaart on tuvastatud. Hoia kaarti vastu telefoni.</string>
|
||||
<string name="data_read">Andmed loetud. Võid edasi minna.</string>
|
||||
<string name="can_save_request">Praegu ei ole rakenduses CAN salvestatud. Kas sa soovid sisestatud CANi salvestada? Sellisel juhul sisestatakse see järgmisel korral automaatselt. Salvestatud CANi saab alati menüüs muuta ja kustutada.</string>
|
||||
<string name="save_can_title">Salvesta CAN</string>
|
||||
<string name="enter_can">Enter ID card\'s CAN (Card Access Number)</string>
|
||||
<string name="length_can">Length of the CAN is wrong</string>
|
||||
<string name="card_detected">Card detected. Hold it against the phone.</string>
|
||||
<string name="data_read">Data read. You can continue.</string>
|
||||
<string name="save_can_title">Save CAN</string>
|
||||
|
||||
<!-- string resources for AuthFragment layout -->
|
||||
<string name="auth_instruction_text">ID kaardiga ühenduse loomiseks pane kaart vastu telefoni</string>
|
||||
<string name="time_left">Aega on jäänud %d sek</string>
|
||||
<string name="no_time">Aeg on otsas</string>
|
||||
<string name="no_success">Vale CAN</string>
|
||||
<string name="auth_instruction_text">Put the ID card against the phone to establish connection</string>
|
||||
<string name="time_left">Time left %d sek</string>
|
||||
<string name="no_time">No time left</string>
|
||||
<string name="no_success">Wrong CAN</string>
|
||||
|
||||
<!-- string resources for UserFragment layout -->
|
||||
<string name="user_name_label">NIMI</string>
|
||||
<string name="user_name_label">NAME</string>
|
||||
<string name="user_name">%1$s %2$s</string>
|
||||
<string name="identification_number_label">ISIKUKOOD</string>
|
||||
<string name="expiration_label">KEHTIV KUNI</string>
|
||||
<string name="citizenship_label">KODAKONDSUS</string>
|
||||
<string name="gender_label">SUGU</string>
|
||||
<string name="clear_button">UNUSTA</string>
|
||||
<string name="identification_number_label">IDENTIFICATION NUMBER</string>
|
||||
<string name="expiration_label">DATE OF EXPIRY</string>
|
||||
<string name="citizenship_label">CITIZENSHIP</string>
|
||||
<string name="gender_label">SEX</string>
|
||||
<string name="clear_button">FORGET</string>
|
||||
|
||||
<!-- string resources for ResultFragment layout-->
|
||||
<string name="result_text">See Fragment vastutab vastuse tagastamise eest.</string>
|
||||
<string name="result_info">Hiljem sulgeb rakendus automaatselt.</string>
|
||||
|
||||
<!-- menu -->
|
||||
<string name="menu_settings_title">Seaded</string>
|
||||
<string name="menu_language_title">Keel</string>
|
||||
<string name="menu_action_unavailable">Toiming pole hetkel saadaval</string>
|
||||
<string name="menu_settings_title">Settings</string>
|
||||
<string name="menu_language_title">Language</string>
|
||||
<string name="menu_action_unavailable">Currently unavailable</string>
|
||||
<string name="saved_can">CAN: %s</string>
|
||||
<string name="can_add">Lisa CAN</string>
|
||||
<string name="can_delete">Kustuta CAN</string>
|
||||
<string name="can_add">Add CAN</string>
|
||||
<string name="can_delete">Delete CAN</string>
|
||||
<string name="saved_pin">PIN1: %s</string>
|
||||
<string name="pin1_add">Lisa PIN1</string>
|
||||
<string name="pin1_delete">Kustuta PIN1</string>
|
||||
<string name="missing">puudub</string>
|
||||
<string name="show">NÄITA</string>
|
||||
<string name="hide">PEIDA</string>
|
||||
<string name="pin1_add">Add PIN1</string>
|
||||
<string name="pin1_delete">Delete PIN1</string>
|
||||
<string name="missing">not saved</string>
|
||||
<string name="show">SHOW</string>
|
||||
<string name="hide">HIDE</string>
|
||||
<string name="hidden_pin">****</string>
|
||||
<string name="unavailable">Seaded pole hetkel saadaval</string>
|
||||
<string name="unavailable">Settings currently unavailabe</string>
|
||||
<string name="can_save_request">CAN is currently not saved. Do you wish to save the CAN? Saved CAN will be entered automatically in the future. Saved CAN can be changed and deleted in the settings menu.</string>
|
||||
</resources>
|
||||
@@ -24,6 +24,12 @@
|
||||
<string name="pin_save_request">Praegu ei ole rakenduses PIN 1 salvestatud. Kas sa soovid sisestatud PIN 1-te salvestada? Sellisel juhul sisestatakse see järgmisel korral automaatselt. Salvestatud PIN 1-te saab alati menüüs muuta ja kustutada.</string>
|
||||
<string name="save_pin_title">Salvesta PIN 1</string>
|
||||
|
||||
<!-- string resources for Pin2Fragment -->
|
||||
<string name="pin2_fragment">Palun sisesta PIN 2</string>
|
||||
<string name="enter_pin2">PIN 2</string>
|
||||
<string name="example_pin2">Näide. 123456</string>
|
||||
<string name="length_pin2">PIN 2 lubatud pikkus on 5..12</string>
|
||||
|
||||
<!-- string resources for CanFragment -->
|
||||
<string name="example_can">Näide. 123456</string>
|
||||
<string name="text_can">CAN</string>
|
||||
@@ -48,6 +54,10 @@
|
||||
<string name="citizenship_label">KODAKONDSUS</string>
|
||||
<string name="gender_label">SUGU</string>
|
||||
|
||||
<!-- string resources for ResultFragment layout-->
|
||||
<string name="result_text">See Fragment vastutab vastuse tagastamise eest.</string>
|
||||
<string name="result_info">Hiljem sulgeb rakendus automaatselt.</string>
|
||||
|
||||
<!-- menu -->
|
||||
<string name="menu_settings_title">Seaded</string>
|
||||
<string name="menu_language_title">Keel</string>
|
||||
|
||||
@@ -2,65 +2,75 @@
|
||||
<string name="app_name">NFC authentication</string>
|
||||
<string name="home_fragment">Work in progress</string>
|
||||
|
||||
<string name="begin_text">LOE ID KAARTI</string>
|
||||
<string name="next_text">EDASI</string>
|
||||
<string name="cancel_text">KATKESTA</string>
|
||||
<string name="save_text">SALVESTA</string>
|
||||
<string name="deny_text">EI</string>
|
||||
<string name="return_text">TAGASI</string>
|
||||
<string name="begin_text">READ ID CARD</string>
|
||||
<string name="next_text">NEXT</string>
|
||||
<string name="cancel_text">CANCEL</string>
|
||||
<string name="save_text">SAVE</string>
|
||||
<string name="deny_text">NO</string>
|
||||
<string name="return_text">BACK</string>
|
||||
|
||||
<!-- string resources for HomeFragment -->
|
||||
<string name="pin_status_saved">PIN 1 on salvestatud</string>
|
||||
<string name="pin_status_negative">PIN 1 ei ole salvestatud</string>
|
||||
<string name="can_status_saved">CAN on salvestatud</string>
|
||||
<string name="can_status_negative">CAN ei ole salvestatud</string>
|
||||
<string name="pin_status_saved">PIN 1 saved</string>
|
||||
<string name="pin_status_negative">PIN 1 not saved</string>
|
||||
<string name="can_status_saved">CAN saved</string>
|
||||
<string name="can_status_negative">CAN not saved</string>
|
||||
|
||||
<!-- string resources for PinFragment -->
|
||||
<string name="pin_fragment">Palun sisesta PIN 1</string>
|
||||
<string name="pin_fragment">Please enter PIN 1</string>
|
||||
<string name="enter_pin">PIN 1</string>
|
||||
<string name="example_pin">Näide. 1234</string>
|
||||
<string name="length_pin">PIN 1 lubatud pikkus on 4..12</string>
|
||||
<string name="pin_save_request">Praegu ei ole rakenduses PIN 1 salvestatud. Kas sa soovid sisestatud PIN 1-te salvestada? Sellisel juhul sisestatakse see järgmisel korral automaatselt. Salvestatud PIN 1-te saab alati menüüs muuta ja kustutada.</string>
|
||||
<string name="save_pin_title">Salvesta PIN 1</string>
|
||||
<string name="example_pin">Example. 1234</string>
|
||||
<string name="length_pin">Allowed length for PIN 1 is 4..12</string>
|
||||
<string name="pin_save_request">PIN 1 is currently not saved. Do you wish to save the entered PIN 1? Saved PIN 1 will be entered automatically in the future. Saved PIN 1 can be changed and deleted in the settings menu.</string>
|
||||
<string name="save_pin_title">Save PIN 1</string>
|
||||
|
||||
<!-- string resources for Pin2Fragment -->
|
||||
<string name="pin2_fragment">Please enter PIN 2</string>
|
||||
<string name="enter_pin2">PIN 2</string>
|
||||
<string name="example_pin2">Example. 123456</string>
|
||||
<string name="length_pin2">Allowed length for PIN 2 is 5..12</string>
|
||||
|
||||
<!-- string resources for CanFragment -->
|
||||
<string name="example_can">Näide. 123456</string>
|
||||
<string name="example_can">Example. 123456</string>
|
||||
<string name="text_can">CAN</string>
|
||||
<string name="enter_can">Sisesta ID kaardi CAN (Card Access Number)</string>
|
||||
<string name="length_can">CANi pikkus on vale</string>
|
||||
<string name="card_detected">Kaart on tuvastatud. Hoia kaarti vastu telefoni.</string>
|
||||
<string name="data_read">Andmed loetud. Võid edasi minna.</string>
|
||||
<string name="can_save_request">Praegu ei ole rakenduses CAN salvestatud. Kas sa soovid sisestatud CANi salvestada? Sellisel juhul sisestatakse see järgmisel korral automaatselt. Salvestatud CANi saab alati menüüs muuta ja kustutada.</string>
|
||||
<string name="save_can_title">Salvesta CAN</string>
|
||||
<string name="enter_can">Enter ID card\'s CAN (Card Access Number)</string>
|
||||
<string name="length_can">Length of the CAN is wrong</string>
|
||||
<string name="card_detected">Card detected. Hold it against the phone.</string>
|
||||
<string name="data_read">Data read. You can continue.</string>
|
||||
<string name="can_save_request">CAN is currently not saved. Do you wish to save the CAN? Saved CAN will be entered automatically in the future. Saved CAN can be changed and deleted in the settings menu.</string>
|
||||
<string name="save_can_title">Save CAN</string>
|
||||
|
||||
<!-- string resources for AuthFragment layout -->
|
||||
<string name="auth_instruction_text">ID kaardiga ühenduse loomiseks pane kaart vastu telefoni</string>
|
||||
<string name="time_left">Aega on jäänud %d sek</string>
|
||||
<string name="no_time">Aeg on otsas</string>
|
||||
<string name="no_success">Vale CAN</string>
|
||||
<string name="auth_instruction_text">Put the ID card against the phone to establish connection</string>
|
||||
<string name="time_left">Time left %d sek</string>
|
||||
<string name="no_time">No time left</string>
|
||||
<string name="no_success">Wrong CAN</string>
|
||||
|
||||
<!-- string resources for UserFragment layout -->
|
||||
<string name="user_name_label">NIMI</string>
|
||||
<string name="user_name_label">NAME</string>
|
||||
<string name="user_name">%1$s %2$s</string>
|
||||
<string name="identification_number_label">ISIKUKOOD</string>
|
||||
<string name="expiration_label">KEHTIV KUNI</string>
|
||||
<string name="citizenship_label">KODAKONDSUS</string>
|
||||
<string name="gender_label">SUGU</string>
|
||||
<string name="clear_button">UNUSTA</string>
|
||||
<string name="identification_number_label">IDENTIFICATION NUMBER</string>
|
||||
<string name="expiration_label">DATE OF EXPIRY</string>
|
||||
<string name="citizenship_label">CITIZENSHIP</string>
|
||||
<string name="gender_label">SEX</string>
|
||||
<string name="clear_button">FORGET</string>
|
||||
|
||||
<!-- string resources for ResultFragment layout-->
|
||||
<string name="result_text">See Fragment vastutab vastuse tagastamise eest.</string>
|
||||
<string name="result_info">Hiljem sulgeb rakendus automaatselt.</string>
|
||||
|
||||
<!-- menu -->
|
||||
<string name="menu_settings_title">Seaded</string>
|
||||
<string name="menu_language_title">Keel</string>
|
||||
<string name="menu_action_unavailable">Toiming pole hetkel saadaval</string>
|
||||
<string name="menu_settings_title">Settings</string>
|
||||
<string name="menu_language_title">Language</string>
|
||||
<string name="menu_action_unavailable">Currently unavailable</string>
|
||||
<string name="saved_can">CAN: %s</string>
|
||||
<string name="can_add">Lisa CAN</string>
|
||||
<string name="can_delete">Kustuta CAN</string>
|
||||
<string name="can_add">Add CAN</string>
|
||||
<string name="can_delete">Delete CAN</string>
|
||||
<string name="saved_pin">PIN1: %s</string>
|
||||
<string name="pin1_add">Lisa PIN 1</string>
|
||||
<string name="pin1_delete">Kustuta PIN 1</string>
|
||||
<string name="missing">puudub</string>
|
||||
<string name="show">NÄITA</string>
|
||||
<string name="hide">PEIDA</string>
|
||||
<string name="pin1_add">Add PIN 1</string>
|
||||
<string name="pin1_delete">Delete PIN 1</string>
|
||||
<string name="missing">not saved</string>
|
||||
<string name="show">SHOW</string>
|
||||
<string name="hide">HIDE</string>
|
||||
<string name="hidden_pin">****</string>
|
||||
<string name="unavailable">Seaded pole hetkel saadaval</string>
|
||||
<string name="unavailable">Settings currently unavailable</string>
|
||||
</resources>
|
||||
Reference in New Issue
Block a user