diff --git a/app/src/main/java/com/atm/bondowowo/BondowowoApp.kt b/app/src/main/java/com/atm/bondowowo/BondowowoApp.kt index b3bf28ecf14175afe24cd093bbcdd92be8ac813d..c52591accbab03846ed52308e2396d774068895a 100644 --- a/app/src/main/java/com/atm/bondowowo/BondowowoApp.kt +++ b/app/src/main/java/com/atm/bondowowo/BondowowoApp.kt @@ -23,12 +23,12 @@ class BondowowoApp : Application() { } override fun onTokenInvalid() { -// val intent = Intent(context, LoginActivity::class.java) -// intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK -// context.startActivity(intent) -// if (context is Activity) { -// context.finish() -// } + val intent = Intent(context, LoginActivity::class.java) + intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK + context.startActivity(intent) + if (context is Activity) { + context.finish() + } } override fun onNetworkError() { diff --git a/app/src/main/java/com/atm/bondowowo/LoginActivity.kt b/app/src/main/java/com/atm/bondowowo/LoginActivity.kt index 662c605acf0681d69412b6371696ca5ce8c62c00..3532569dca1363718c65630b32cbc98d28360fa6 100644 --- a/app/src/main/java/com/atm/bondowowo/LoginActivity.kt +++ b/app/src/main/java/com/atm/bondowowo/LoginActivity.kt @@ -1,5 +1,6 @@ package com.atm.bondowowo +import android.content.Context import android.content.Intent import android.os.Bundle import android.widget.Button @@ -9,9 +10,9 @@ import androidx.appcompat.app.AppCompatActivity import androidx.lifecycle.Observer import com.atm.bondowowo.data.model.LoginRequest import com.atm.bondowowo.utils.DialogHelper -import com.atm.bondowowo.utils.NetworkHelper import com.atm.bondowowo.utils.NetworkStateLiveData import com.atm.bondowowo.utils.NetworkUtils.apiService +import com.atm.bondowowo.utils.UserPreferencesUtil import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch @@ -27,29 +28,48 @@ class LoginActivity : AppCompatActivity() { super.onCreate(savedInstanceState) setContentView(R.layout.activity_login) + initViews() + setupNetworkStateObserver() + checkAuthenticationStatus() + } + + private fun initViews() { + etUsername = findViewById(R.id.etUsername) + etPassword = findViewById(R.id.etPassword) + btnLogin = findViewById(R.id.btnLogin) + btnLogin.setOnClickListener { performLogin(this) } + } + + private fun setupNetworkStateObserver() { val networkStateLiveData = NetworkStateLiveData(this) networkStateLiveData.observe(this, Observer { isConnected -> if (!isConnected) { DialogHelper.showNoInternetDialog(this) } }) + } - CoroutineScope(Dispatchers.Main).launch { - if (isUserAuthenticated()) { - navigateToMainActivity() - } else { - etUsername = findViewById(R.id.etUsername) - etPassword = findViewById(R.id.etPassword) - btnLogin = findViewById(R.id.btnLogin) - - btnLogin.setOnClickListener { - performLogin() + private fun checkAuthenticationStatus() { + CoroutineScope(Dispatchers.IO).launch { + try { + val isAuthenticated = isUserAuthenticated() + if (isAuthenticated) { + navigateToMainActivity() + } + } catch (e: Exception) { + withContext(Dispatchers.Main) { + Toast.makeText( + this@LoginActivity, + "You might have unstable connection", + Toast.LENGTH_SHORT + ) + .show() } } } } - private fun performLogin() { + private fun performLogin(context: Context) { val email = etUsername.text.toString() val password = etPassword.text.toString() @@ -62,13 +82,19 @@ class LoginActivity : AppCompatActivity() { val loginResponse = response.body() val token = loginResponse?.token - saveTokenSecurely(token) + if (token != null) { + UserPreferencesUtil.addJWT(context, token) + } startActivity(Intent(this@LoginActivity, MainActivity::class.java)) finish() } else { withContext(Dispatchers.Main) { - Toast.makeText(this@LoginActivity, "Invalid Credentials", Toast.LENGTH_SHORT) + Toast.makeText( + this@LoginActivity, + "Invalid Credentials", + Toast.LENGTH_SHORT + ) .show() } } @@ -81,13 +107,6 @@ class LoginActivity : AppCompatActivity() { } } - private fun saveTokenSecurely(token: String?) { - val sharedPreferences = getSharedPreferences("AUTH_PREFS", MODE_PRIVATE) - val editor = sharedPreferences.edit() - editor.putString("JWT_TOKEN", token) - editor.apply() - } - private suspend fun isUserAuthenticated(): Boolean { val sharedPreferences = getSharedPreferences("AUTH_PREFS", MODE_PRIVATE) val token = sharedPreferences.getString("JWT_TOKEN", null) @@ -103,18 +122,18 @@ class LoginActivity : AppCompatActivity() { private suspend fun isTokenValid(token: String): Boolean { // Karena lagi malas login - return true -// return try { -// val response = apiService.verifyToken("Bearer $token") -// if (response.isSuccessful) { -// val responseBody = response.body() -// val isString = responseBody is String -// return !isString -// } else { -// false -// } -// } catch (e: Exception) { -// false -// } +// return true + return try { + val response = apiService.verifyToken("Bearer $token") + if (response.isSuccessful) { + val responseBody = response.body() + val isString = responseBody is String + return !isString + } else { + false + } + } catch (e: Exception) { + false + } } } \ No newline at end of file diff --git a/app/src/main/java/com/atm/bondowowo/MainActivity.kt b/app/src/main/java/com/atm/bondowowo/MainActivity.kt index 5980de34a2d83b775e00ab2232e919a586922d7b..13fd9a1e61652d4c73eb00ec1bf34df5468cdc56 100644 --- a/app/src/main/java/com/atm/bondowowo/MainActivity.kt +++ b/app/src/main/java/com/atm/bondowowo/MainActivity.kt @@ -27,11 +27,11 @@ class MainActivity : AppCompatActivity() { setContentView(binding.root) val networkStateLiveData = NetworkStateLiveData(this) - networkStateLiveData.observe(this, Observer { isConnected -> + networkStateLiveData.observe(this) { isConnected -> if (!isConnected) { DialogHelper.showNoInternetDialog(this) } - }) + } CoroutineScope(Dispatchers.Main).launch { if (!isUserAuthenticated()) { @@ -64,28 +64,28 @@ class MainActivity : AppCompatActivity() { private suspend fun isTokenValid(token: String): Boolean { // Lagi malas login juga - return true -// return try { -// val response = NetworkUtils.apiService.verifyToken("Bearer $token") -// if (response.isSuccessful) { -// val responseBody = response.body() -// val isString = responseBody is String -// return !isString -// } else { -// Toast.makeText( -// this@MainActivity, -// "Session Expired, Please Re login", -// Toast.LENGTH_SHORT -// ).show() -// false -// } -// } catch (e: Exception) { -// Toast.makeText( -// this@MainActivity, -// "An error occurred, Please Re login", -// Toast.LENGTH_SHORT -// ).show() -// false -// } +// return true + return try { + val response = NetworkUtils.apiService.verifyToken("Bearer $token") + if (response.isSuccessful) { + val responseBody = response.body() + val isString = responseBody is String + return !isString + } else { + Toast.makeText( + this@MainActivity, + "Session Expired, Please Re login", + Toast.LENGTH_SHORT + ).show() + false + } + } catch (e: Exception) { + Toast.makeText( + this@MainActivity, + "An error occurred, Please Re login", + Toast.LENGTH_SHORT + ).show() + false + } } } diff --git a/app/src/main/java/com/atm/bondowowo/ui/settings/SettingsFragment.kt b/app/src/main/java/com/atm/bondowowo/ui/settings/SettingsFragment.kt index 6afe42f25df48f5f456f320bb17786c2f765afcc..cd67ee39f695de16f64e3583e3d21a20e3104730 100644 --- a/app/src/main/java/com/atm/bondowowo/ui/settings/SettingsFragment.kt +++ b/app/src/main/java/com/atm/bondowowo/ui/settings/SettingsFragment.kt @@ -8,13 +8,15 @@ import android.view.ViewGroup import android.widget.Button import android.widget.LinearLayout import androidx.fragment.app.Fragment +import com.atm.bondowowo.LoginActivity import com.atm.bondowowo.R import com.atm.bondowowo.data.local.database.AppDatabase import com.atm.bondowowo.utils.ExportToFileUtil import com.atm.bondowowo.utils.SendEmailUtil +import com.atm.bondowowo.utils.UserPreferencesUtil -class SettingsFragment : Fragment(){ +class SettingsFragment : Fragment() { private lateinit var linearLayout: LinearLayout private lateinit var btn_export: Button private lateinit var btn_send_email: Button @@ -45,12 +47,14 @@ class SettingsFragment : Fragment(){ } btn_logout.setOnClickListener { - TODO("Logout") + UserPreferencesUtil.removeJWT(requireContext()) + val intent = + Intent(requireContext(), LoginActivity::class.java) + startActivity(intent) } return view } - } \ No newline at end of file diff --git a/app/src/main/java/com/atm/bondowowo/utils/BackgroundJWTCheckerUtil.kt b/app/src/main/java/com/atm/bondowowo/utils/BackgroundJWTCheckerUtil.kt index 5af4f8c09a09732e962262245b768c1eb5e47ccb..047a89ebdcd3177f83426485c28e808518820b7b 100644 --- a/app/src/main/java/com/atm/bondowowo/utils/BackgroundJWTCheckerUtil.kt +++ b/app/src/main/java/com/atm/bondowowo/utils/BackgroundJWTCheckerUtil.kt @@ -1,8 +1,13 @@ package com.atm.bondowowo.utils -import androidx.appcompat.app.AppCompatActivity import android.content.Context -import kotlinx.coroutines.* +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch class BackgroundJWTChecker { @@ -18,11 +23,7 @@ class BackgroundJWTChecker { fun startChecking(context: Context, callback: Callback) { job = GlobalScope.launch(Dispatchers.IO) { while (isActive) { - val sharedPreferences = context.getSharedPreferences( - "AUTH_PREFS", - AppCompatActivity.MODE_PRIVATE - ) - val token = sharedPreferences.getString("JWT_TOKEN", null) + val token = UserPreferencesUtil.getJWT(context) if (token != null) { verifyToken(token, callback) } else { diff --git a/app/src/main/java/com/atm/bondowowo/utils/SendEmailUtil.kt b/app/src/main/java/com/atm/bondowowo/utils/SendEmailUtil.kt index 2d03679d6bfab7207c03d70ff17199f50773b544..4fb1ee3cf8fa59742a18f4d35ec024faf37a1c9d 100644 --- a/app/src/main/java/com/atm/bondowowo/utils/SendEmailUtil.kt +++ b/app/src/main/java/com/atm/bondowowo/utils/SendEmailUtil.kt @@ -19,23 +19,32 @@ object SendEmailUtil { val file = getLatestFileFromStorage(context) if (file != null && file.exists()) { - val uri = FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file) + val uri = + FileProvider.getUriForFile(context, "${context.packageName}.fileprovider", file) - val resInfoList = context.packageManager.queryIntentActivities(Intent(Intent.ACTION_SEND).apply { - type = "application/vnd.ms-excel" - putExtra(Intent.EXTRA_STREAM, uri) - }, Context.MODE_PRIVATE) + val resInfoList = + context.packageManager.queryIntentActivities(Intent(Intent.ACTION_SEND).apply { + type = "application/vnd.ms-excel" + putExtra(Intent.EXTRA_STREAM, uri) + }, Context.MODE_PRIVATE) for (resolveInfo in resInfoList) { val packageName = resolveInfo.activityInfo.packageName - context.grantUriPermission(packageName, uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION) + context.grantUriPermission( + packageName, + uri, + Intent.FLAG_GRANT_WRITE_URI_PERMISSION or Intent.FLAG_GRANT_READ_URI_PERMISSION + ) } val emailIntent = Intent(Intent.ACTION_SEND) emailIntent.type = "application/vnd.ms-excel" - emailIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf("shidqizh@gmail.com")) // masi pr ini benerin ke email pengguna sekarang + emailIntent.putExtra(Intent.EXTRA_EMAIL, arrayOf(UserPreferencesUtil.getEmail(context))) emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Export File") - emailIntent.putExtra(Intent.EXTRA_TEXT, "Berikut terlampir file transaksi dalam format spreadsheet.") + emailIntent.putExtra( + Intent.EXTRA_TEXT, + "Berikut terlampir file transaksi dalam format spreadsheet." + ) emailIntent.putExtra(Intent.EXTRA_STREAM, uri) try { @@ -44,7 +53,8 @@ object SendEmailUtil { Toast.makeText(context, "No email clients installed.", Toast.LENGTH_SHORT).show() } } else { - Toast.makeText(context, "No transaction file found or attached.", Toast.LENGTH_SHORT).show() + Toast.makeText(context, "No transaction file found or attached.", Toast.LENGTH_SHORT) + .show() } } @@ -56,7 +66,8 @@ object SendEmailUtil { return null } - val files = directory.listFiles()?.filter { it.isFile }?.sortedByDescending { it.lastModified() } + val files = + directory.listFiles()?.filter { it.isFile }?.sortedByDescending { it.lastModified() } return files?.firstOrNull() } } diff --git a/app/src/main/java/com/atm/bondowowo/utils/UserPreferencesUtil.kt b/app/src/main/java/com/atm/bondowowo/utils/UserPreferencesUtil.kt new file mode 100644 index 0000000000000000000000000000000000000000..3b59fd524b9c7f466794e044597f8fa88648c8c5 --- /dev/null +++ b/app/src/main/java/com/atm/bondowowo/utils/UserPreferencesUtil.kt @@ -0,0 +1,53 @@ +package com.atm.bondowowo.utils + +import android.content.Context +import androidx.appcompat.app.AppCompatActivity + +object UserPreferencesUtil { + private const val PREF_NAME = "AUTH_PREFS" + private const val KEY_EMAIL = "EMAIL" + private const val KEY_JWT = "JWT_TOKEN" + fun addJWT(context: Context, token: String) { + val sharedPreferences = + context.getSharedPreferences(PREF_NAME, AppCompatActivity.MODE_PRIVATE) + val editor = sharedPreferences.edit() + editor.putString(KEY_JWT, token) + editor.apply() + } + + fun removeJWT(context: Context) { + val sharedPreferences = + context.getSharedPreferences(PREF_NAME, AppCompatActivity.MODE_PRIVATE) + val editor = sharedPreferences.edit() + editor.remove(KEY_JWT) + editor.apply() + } + + fun getJWT(context: Context): String? { + val sharedPreferences = + context.getSharedPreferences(PREF_NAME, AppCompatActivity.MODE_PRIVATE) + return sharedPreferences.getString(KEY_JWT, "") + } + + fun addEmail(context: Context, email: String) { + val sharedPreferences = + context.getSharedPreferences(PREF_NAME, AppCompatActivity.MODE_PRIVATE) + val editor = sharedPreferences.edit() + editor.putString(KEY_EMAIL, email) + editor.apply() + } + + fun removeEmail(context: Context) { + val sharedPreferences = + context.getSharedPreferences(PREF_NAME, AppCompatActivity.MODE_PRIVATE) + val editor = sharedPreferences.edit() + editor.remove(KEY_EMAIL) + editor.apply() + } + + fun getEmail(context: Context): String? { + val sharedPreferences = + context.getSharedPreferences(PREF_NAME, AppCompatActivity.MODE_PRIVATE) + return sharedPreferences.getString(KEY_EMAIL, "") + } +}