diff --git a/app/src/main/java/com/example/bondoman/BondomanApp.kt b/app/src/main/java/com/example/bondoman/BondomanApp.kt index bf361b8c0999beb56e9092947bd7698a2e3909e8..e92f2411ec855f465b35fe14270371a41c898bf1 100644 --- a/app/src/main/java/com/example/bondoman/BondomanApp.kt +++ b/app/src/main/java/com/example/bondoman/BondomanApp.kt @@ -12,6 +12,7 @@ class BondomanApp : Application() { AppDatabase.getInstance(this) val filter = IntentFilter(ACTION_RANDOM_TRANSACTION) + registerReceiver(randomReceiver, filter, RECEIVER_NOT_EXPORTED) } @@ -21,5 +22,6 @@ class BondomanApp : Application() { const val ACTION_AUTHORIZED = "com.example.bondoman.ACTION_AUTHORIZED" const val ACTION_UNAUTHORIZED = "com.example.bondoman.ACTION_UNAUTHORIZED" const val LOCATION_MARK: Double = 200.0 + const val JWT_CHECK_INTERVAL: Long = 60000 } } \ No newline at end of file diff --git a/app/src/main/java/com/example/bondoman/MainActivity.kt b/app/src/main/java/com/example/bondoman/MainActivity.kt index db3b0685d8c76466c2eb2d28cb5796449b35a432..e253de412ad4db37043331b9e3c38f5d4db82239 100644 --- a/app/src/main/java/com/example/bondoman/MainActivity.kt +++ b/app/src/main/java/com/example/bondoman/MainActivity.kt @@ -1,34 +1,52 @@ package com.example.bondoman import android.content.Intent +import android.content.IntentFilter import android.os.Bundle +import android.util.Log import androidx.appcompat.app.AppCompatActivity +import androidx.lifecycle.ViewModelProvider +import androidx.localbroadcastmanager.content.LocalBroadcastManager +import com.example.bondoman.services.SessionManager import com.example.bondoman.ui.hub.HubActivity import com.example.bondoman.ui.login.LoginActivity +import com.example.bondoman.viewmodel.auth.AuthViewModel +import com.example.bondoman.viewmodel.auth.AuthViewModelFactory class MainActivity : AppCompatActivity() { + private lateinit var authViewModel: AuthViewModel + private lateinit var sessionManager: SessionManager + override fun onCreate(savedInstanceState: Bundle?){ super.onCreate(savedInstanceState) - splashScreen() + setContentView(R.layout.activity_main) - val intent: Intent = if(loginCheck()){ - Intent(this, HubActivity::class.java) - } else{ - Intent(this, LoginActivity::class.java) - } + sessionManager = SessionManager(this) - startActivity(intent) - finish() - } + val authViewModelFactory = AuthViewModelFactory() + authViewModel = ViewModelProvider(this, authViewModelFactory)[AuthViewModel::class.java] + + authViewModel.isAuthorized.observe(this) { + it?.let{ + val intent = if (it) { + Intent(this, HubActivity::class.java) + } else { + Intent(this, LoginActivity::class.java) + } - //TODO: Implement Splash screen - private fun splashScreen(){ - println("Splash screen") + startActivity(intent) + finish() + } + } + + authViewModel.removeToken.observe(this) { + if (it) sessionManager.clearToken() + } } - //TODO: Implement Login / network mechanism - private fun loginCheck() : Boolean { - println("Login check") - return false + override fun onResume() { + super.onResume() + val token = sessionManager.getToken() + authViewModel.validate(token) } } diff --git a/app/src/main/java/com/example/bondoman/database/repository/TransactionRepository.kt b/app/src/main/java/com/example/bondoman/database/repository/TransactionRepository.kt index e86553243eee8ed104049e1d19ae4a574d46920f..48f4dd4d1fca43debd796175dcf832ea29d08e0a 100644 --- a/app/src/main/java/com/example/bondoman/database/repository/TransactionRepository.kt +++ b/app/src/main/java/com/example/bondoman/database/repository/TransactionRepository.kt @@ -38,11 +38,9 @@ class TransactionRepository(private val transactionDao: TransactionDao) { transactionDao.deleteAll() } - suspend fun postUploadNota(imageReqBody: RequestBody): Boolean { + suspend fun postUploadNota(imageReqBody: RequestBody, token: String): Boolean { try { - // TODO: Get stored auth token - val authToken = - "Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuaW0iOiIxMzUyMTE0OSIsImlhdCI6MTcxMTgxNTE1OCwiZXhwIjoxNzExODE1NDU4fQ.mASnON98EJmGWmVMdjWB47ef3pwYIVJelaYMpMjy_BY" + val authToken = "Bearer $token" val response = RetrofitClient.uploadInstance.uploadImage( MultipartBody.Part.createFormData( "file", "test", imageReqBody diff --git a/app/src/main/java/com/example/bondoman/services/AuthService.kt b/app/src/main/java/com/example/bondoman/services/AuthService.kt index 1155a5e857dad892e8a7e30fd1cac33ee83deebe..1446a0699f4ed28d5386ca5e476ae2e16073a812 100644 --- a/app/src/main/java/com/example/bondoman/services/AuthService.kt +++ b/app/src/main/java/com/example/bondoman/services/AuthService.kt @@ -9,7 +9,6 @@ import android.os.Looper import android.os.Message import android.os.Process import android.util.Log -import android.widget.Toast import androidx.localbroadcastmanager.content.LocalBroadcastManager import com.example.bondoman.BondomanApp import com.example.bondoman.api.RetrofitClient @@ -18,7 +17,6 @@ import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.cancel import kotlinx.coroutines.delay import kotlinx.coroutines.launch -import kotlinx.coroutines.runBlocking class AuthService : Service() { @@ -27,10 +25,6 @@ class AuthService : Service() { private lateinit var sessionManager: SessionManager private val coroutineScope: CoroutineScope = CoroutineScope(Dispatchers.IO) - companion object { - const val INTERVAL: Long = 60000 - } - private inner class ServiceHandler(looper: Looper) : Handler(looper) { override fun handleMessage(msg: Message) { validate() @@ -40,13 +34,13 @@ class AuthService : Service() { coroutineScope.launch { while(true) { task() - delay(INTERVAL) + delay(BondomanApp.JWT_CHECK_INTERVAL) } } } private suspend fun task() { - Log.d("bg task", Thread.currentThread().toString()) + Log.d("service token", sessionManager.getToken().toString()) val token = sessionManager.getToken() ?: return try { @@ -66,7 +60,6 @@ class AuthService : Service() { override fun onCreate() { - Toast.makeText(this, "service created", Toast.LENGTH_SHORT).show() sessionManager = SessionManager(applicationContext) HandlerThread("ServiceStartArguments", Process.THREAD_PRIORITY_BACKGROUND).apply { diff --git a/app/src/main/java/com/example/bondoman/ui/hub/scan/ScanFragment.kt b/app/src/main/java/com/example/bondoman/ui/hub/scan/ScanFragment.kt index 9d243c1dfd9510bd5f1d295f6755b164914a6f68..dad834b80bcfedcec731318d5c6427c793768040 100644 --- a/app/src/main/java/com/example/bondoman/ui/hub/scan/ScanFragment.kt +++ b/app/src/main/java/com/example/bondoman/ui/hub/scan/ScanFragment.kt @@ -29,6 +29,7 @@ import com.example.bondoman.R import com.example.bondoman.database.AppDatabase import com.example.bondoman.database.repository.TransactionRepository import com.example.bondoman.databinding.FragmentScanBinding +import com.example.bondoman.services.SessionManager import com.example.bondoman.viewmodel.scan.ScanViewModel import com.example.bondoman.viewmodel.scan.ScanViewModelFactory import okhttp3.MediaType @@ -45,6 +46,8 @@ class ScanFragment : Fragment() { private var imageCapture: ImageCapture? = null private lateinit var cameraExecutor: ExecutorService + private lateinit var sessionManager: SessionManager + private val activityResultLauncher = registerForActivityResult( ActivityResultContracts.RequestPermission() ) { isGranted: Boolean -> @@ -98,6 +101,7 @@ class ScanFragment : Fragment() { } cameraExecutor = Executors.newSingleThreadExecutor() + sessionManager = SessionManager(requireActivity()) return binding.root } @@ -189,23 +193,27 @@ class ScanFragment : Fragment() { val byteArray = stream.toByteArray() val imageReqBody = RequestBody.create(MediaType.parse("image/*"), byteArray) - viewLifecycleOwner.lifecycleScope.launchWhenStarted { - val success = scanViewModel.uploadNota(imageReqBody) - - if (success) { - Toast.makeText( - requireActivity(), - getString(R.string.scan_add_toast_success), - Toast.LENGTH_SHORT - ).show() - } else { - Toast.makeText( - requireActivity(), getString(R.string.scan_add_toast_failed), Toast.LENGTH_SHORT - ).show() + val token = sessionManager.getToken() + + token?.let{ + viewLifecycleOwner.lifecycleScope.launchWhenStarted { + val success = scanViewModel.uploadNota(imageReqBody, token) + + if (success) { + Toast.makeText( + requireActivity(), + getString(R.string.scan_add_toast_success), + Toast.LENGTH_SHORT + ).show() + } else { + Toast.makeText( + requireActivity(), getString(R.string.scan_add_toast_failed), Toast.LENGTH_SHORT + ).show() + } } } - + // TODO: if token null } private fun selectPhoto() { diff --git a/app/src/main/java/com/example/bondoman/ui/login/LoginActivity.kt b/app/src/main/java/com/example/bondoman/ui/login/LoginActivity.kt index 916f8639d4adc357a26156e0deaf4051958106e3..e5e5e60cd85afef4caf896b7c63ecb4d6b2807b4 100644 --- a/app/src/main/java/com/example/bondoman/ui/login/LoginActivity.kt +++ b/app/src/main/java/com/example/bondoman/ui/login/LoginActivity.kt @@ -5,7 +5,6 @@ import android.content.Context import android.content.Intent import android.content.IntentFilter import android.os.Bundle -import android.util.Log import android.view.View import android.widget.Toast import androidx.appcompat.app.AppCompatActivity @@ -17,16 +16,13 @@ import com.example.bondoman.databinding.ActivityLoginBinding import com.example.bondoman.models.Credential import com.example.bondoman.services.AuthService import com.example.bondoman.services.SessionManager -import com.example.bondoman.viewmodel.login.AuthViewModel -import com.example.bondoman.viewmodel.login.AuthViewModelFactory -import com.example.bondoman.viewmodel.login.LoginViewModel -import com.example.bondoman.viewmodel.login.LoginViewModelFactory +import com.example.bondoman.viewmodel.auth.LoginViewModel +import com.example.bondoman.viewmodel.auth.LoginViewModelFactory class LoginActivity : AppCompatActivity() { private lateinit var binding: ActivityLoginBinding private lateinit var sessionManager: SessionManager private lateinit var loginViewModel: LoginViewModel - private lateinit var authViewModel: AuthViewModel private var broadcastReceiver = object: BroadcastReceiver() { override fun onReceive(context: Context?, intent: Intent?) { @@ -48,18 +44,7 @@ class LoginActivity : AppCompatActivity() { sessionManager = SessionManager(this) val loginViewModelFactory = LoginViewModelFactory() loginViewModel = ViewModelProvider(this, loginViewModelFactory)[LoginViewModel::class.java] - val authViewModelFactory = AuthViewModelFactory() - authViewModel = ViewModelProvider(this, authViewModelFactory)[AuthViewModel::class.java] - authViewModel.isAuthorized.observe(this) { - if (it) { - navigateToHub() - } - } - - authViewModel.removeToken.observe(this) { - if (it) sessionManager.clearToken() - } loginViewModel.loginToken.observe(this) { if (it != null) { @@ -77,11 +62,6 @@ class LoginActivity : AppCompatActivity() { override fun onResume() { super.onResume() - val token = sessionManager.getToken() - token?.let { - authViewModel.validate(token) - } - LocalBroadcastManager.getInstance(this) .registerReceiver( broadcastReceiver, diff --git a/app/src/main/java/com/example/bondoman/viewmodel/auth/AuthViewModel.kt b/app/src/main/java/com/example/bondoman/viewmodel/auth/AuthViewModel.kt new file mode 100644 index 0000000000000000000000000000000000000000..b5bb9d567a520d15035ff1afdc48df00734f1b1f --- /dev/null +++ b/app/src/main/java/com/example/bondoman/viewmodel/auth/AuthViewModel.kt @@ -0,0 +1,34 @@ +package com.example.bondoman.viewmodel.auth + +import androidx.lifecycle.MutableLiveData +import androidx.lifecycle.ViewModel +import androidx.lifecycle.viewModelScope +import com.example.bondoman.api.RetrofitClient +import kotlinx.coroutines.delay +import kotlinx.coroutines.launch + +class AuthViewModel: ViewModel() { + val isAuthorized = MutableLiveData<Boolean?>(null) + val removeToken = MutableLiveData(false) + + fun validate(token: String?) { + viewModelScope.launch { + if (token == null) { + delay(1000) + isAuthorized.value = false + } else { + try { + val response = RetrofitClient.authInstance.authToken("Bearer $token") + + if (response.code() == 200) { + isAuthorized.value = true + } else if (response.code() == 401) { + isAuthorized.value = false + removeToken.value = true + } + } catch (_: Exception) { + } + } + } + } +} \ No newline at end of file diff --git a/app/src/main/java/com/example/bondoman/viewmodel/login/AuthViewModelFactory.kt b/app/src/main/java/com/example/bondoman/viewmodel/auth/AuthViewModelFactory.kt similarity index 84% rename from app/src/main/java/com/example/bondoman/viewmodel/login/AuthViewModelFactory.kt rename to app/src/main/java/com/example/bondoman/viewmodel/auth/AuthViewModelFactory.kt index 56580f8e4e981e51d35f01eea5db6d5066a8ab0f..3f34331efd2755c25c1c4c325bc1a7a4dea9ee68 100644 --- a/app/src/main/java/com/example/bondoman/viewmodel/login/AuthViewModelFactory.kt +++ b/app/src/main/java/com/example/bondoman/viewmodel/auth/AuthViewModelFactory.kt @@ -1,4 +1,4 @@ -package com.example.bondoman.viewmodel.login +package com.example.bondoman.viewmodel.auth import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider diff --git a/app/src/main/java/com/example/bondoman/viewmodel/login/LoginViewModel.kt b/app/src/main/java/com/example/bondoman/viewmodel/auth/LoginViewModel.kt similarity index 96% rename from app/src/main/java/com/example/bondoman/viewmodel/login/LoginViewModel.kt rename to app/src/main/java/com/example/bondoman/viewmodel/auth/LoginViewModel.kt index 290eaddb5d9d847d93e2ed0d3f40ea9314c6f8bc..654bcb0fbc5b45feb4f8e4a311bdff604d52cb91 100644 --- a/app/src/main/java/com/example/bondoman/viewmodel/login/LoginViewModel.kt +++ b/app/src/main/java/com/example/bondoman/viewmodel/auth/LoginViewModel.kt @@ -1,4 +1,4 @@ -package com.example.bondoman.viewmodel.login +package com.example.bondoman.viewmodel.auth import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel diff --git a/app/src/main/java/com/example/bondoman/viewmodel/login/LoginViewModelFactory.kt b/app/src/main/java/com/example/bondoman/viewmodel/auth/LoginViewModelFactory.kt similarity index 84% rename from app/src/main/java/com/example/bondoman/viewmodel/login/LoginViewModelFactory.kt rename to app/src/main/java/com/example/bondoman/viewmodel/auth/LoginViewModelFactory.kt index 9e3225221829e747043bec93dbf030f28a92847d..b257fbc8efa3d1a625cbb69a5ac3387fbad5626d 100644 --- a/app/src/main/java/com/example/bondoman/viewmodel/login/LoginViewModelFactory.kt +++ b/app/src/main/java/com/example/bondoman/viewmodel/auth/LoginViewModelFactory.kt @@ -1,4 +1,4 @@ -package com.example.bondoman.viewmodel.login +package com.example.bondoman.viewmodel.auth import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider diff --git a/app/src/main/java/com/example/bondoman/viewmodel/login/AuthViewModel.kt b/app/src/main/java/com/example/bondoman/viewmodel/login/AuthViewModel.kt deleted file mode 100644 index 4bd390f3e1ebfabe9d1e63c90ea050e9dd59587c..0000000000000000000000000000000000000000 --- a/app/src/main/java/com/example/bondoman/viewmodel/login/AuthViewModel.kt +++ /dev/null @@ -1,32 +0,0 @@ -package com.example.bondoman.viewmodel.login - -import android.util.Log -import androidx.lifecycle.MutableLiveData -import androidx.lifecycle.ViewModel -import androidx.lifecycle.viewModelScope -import com.example.bondoman.api.RetrofitClient -import com.example.bondoman.models.Credential -import kotlinx.coroutines.launch -import java.net.SocketTimeoutException - -class AuthViewModel: ViewModel() { - val isAuthorized = MutableLiveData(false) - val removeToken = MutableLiveData(false) - - fun validate(token: String) { - viewModelScope.launch { - try { - Log.d("bondoman cuy", "validating...") - val response = RetrofitClient.authInstance.authToken("Bearer $token") - - if (response.code() == 200) { - isAuthorized.value = true - } else if (response.code() == 401){ - Log.d("bondoman cuy", token) - response.errorBody()?.string()?.let { Log.d("bondoman cuy", it) } - removeToken.value = true - } - } catch (_: SocketTimeoutException) { } - } - } -} \ No newline at end of file diff --git a/app/src/main/java/com/example/bondoman/viewmodel/scan/ScanViewModel.kt b/app/src/main/java/com/example/bondoman/viewmodel/scan/ScanViewModel.kt index 117402c85f119c656ad71b56715f4fd8b907a413..34cac63b79de69e0700219b495978dff2609c72a 100644 --- a/app/src/main/java/com/example/bondoman/viewmodel/scan/ScanViewModel.kt +++ b/app/src/main/java/com/example/bondoman/viewmodel/scan/ScanViewModel.kt @@ -8,7 +8,7 @@ import okhttp3.RequestBody class ScanViewModel(private val repository: TransactionRepository) : ViewModel() { val isCameraPermissionGranted = MutableLiveData(false) - suspend fun uploadNota(imageReqBody: RequestBody): Boolean { - return repository.postUploadNota(imageReqBody) + suspend fun uploadNota(imageReqBody: RequestBody, token: String): Boolean { + return repository.postUploadNota(imageReqBody, token) } } \ No newline at end of file diff --git a/app/src/main/res/layout/activity_login.xml b/app/src/main/res/layout/activity_login.xml index 9573a5991a419141d0ed95da041215b9473727dd..818e5aac98e2fc2e1ddaf6f95fa12100006765ff 100644 --- a/app/src/main/res/layout/activity_login.xml +++ b/app/src/main/res/layout/activity_login.xml @@ -63,7 +63,7 @@ android:layout_width="match_parent" android:layout_height="16pt" android:ems="10" - android:inputType="text" + android:inputType="textPassword" android:background="@color/gray" android:textColor="@color/black"/>