From a7a9e66351db1901c2048f5b9e92a67899022f2a Mon Sep 17 00:00:00 2001 From: 0xzre <alilo.ghazali@gmail.com> Date: Mon, 1 Apr 2024 22:45:31 +0700 Subject: [PATCH] fix email user & userpreference --- .../java/com/atm/bondowowo/BondowowoApp.kt | 12 +-- .../java/com/atm/bondowowo/LoginActivity.kt | 87 +++++++++++-------- .../java/com/atm/bondowowo/MainActivity.kt | 50 +++++------ .../bondowowo/ui/settings/SettingsFragment.kt | 10 ++- .../utils/BackgroundJWTCheckerUtil.kt | 15 ++-- .../com/atm/bondowowo/utils/SendEmailUtil.kt | 31 ++++--- .../bondowowo/utils/UserPreferencesUtil.kt | 53 +++++++++++ 7 files changed, 173 insertions(+), 85 deletions(-) create mode 100644 app/src/main/java/com/atm/bondowowo/utils/UserPreferencesUtil.kt diff --git a/app/src/main/java/com/atm/bondowowo/BondowowoApp.kt b/app/src/main/java/com/atm/bondowowo/BondowowoApp.kt index b3bf28e..c52591a 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 662c605..3532569 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 5980de3..13fd9a1 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 6afe42f..cd67ee3 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 5af4f8c..047a89e 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 2d03679..4fb1ee3 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 0000000..3b59fd5 --- /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, "") + } +} -- GitLab